An original Thinka practice paper modelled on the structure and difficulty of the Jun 2023 Cambridge OCR A Level Computer Science - H446 paper. Not affiliated with or reproduced from Cambridge.
Paper 1: Computer Systems
Answer all questions. Calculators are not allowed. Quality of extended response will be assessed in questions marked with an asterisk (*).
32 Question · 118 marks
Question 1 · short_answer
2 marks
Explain the purpose of the Program Counter (PC) during the fetch stage of the Fetch-Decode-Execute cycle.
Show answer & marking schemeHide answer & marking scheme
Worked solution
During the fetch phase of the cycle, the Program Counter (PC) holds the address of the next instruction. This address is sent via the address bus to the Memory Address Register (MAR). Immediately after, or simultaneously, the PC is incremented by one so that it contains the address of the next instruction in sequence.
Marking scheme
1 mark: State that the PC holds the address of the next instruction to be fetched (or copies this address to the MAR). 1 mark: State that the PC is incremented to point to the subsequent instruction.
Question 2 · short_answer
2 marks
Describe one advantage and one disadvantage of using a CISC (Complex Instruction Set Computer) architecture compared to a RISC (Reduced Instruction Set Computer) architecture.
Show answer & marking schemeHide answer & marking scheme
Worked solution
CISC architectures have a rich instruction set. An advantage is that compilers have less work to do, and program files are smaller because complex tasks can be written in fewer instructions, consuming less main memory. A disadvantage is that CISC chips are physically larger, have more complex circuitry, consume more power, generate more heat, and are harder to design for efficient pipelining because instructions have variable sizes and execution times.
Marking scheme
1 mark for a valid advantage (e.g., smaller executable files / less RAM usage / simpler compiler design). 1 mark for a valid disadvantage (e.g., complex processor design / higher power consumption / higher cost / difficulty implementing pipelining).
Question 3 · short_answer
2 marks
Describe the difference between paging and segmentation when managing virtual memory.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Paging is a physical allocation method where the address space is split into equal-sized pages (e.g., 4KB), regardless of the code structure. Segmentation is a logical allocation method where programs are split into variable-sized segments based on logical blocks, such as subroutines, modules, or stack structures.
Marking scheme
1 mark: Paging uses fixed-size or physical blocks. 1 mark: Segmentation uses variable-size or logical blocks (based on program structure/logical divisions).
Question 4 · short_answer
2 marks
Explain the role of the linker when translating program source code into an executable file.
Show answer & marking schemeHide answer & marking scheme
Worked solution
A compiler compiles source code into object code. The linker is then responsible for combining this object code with other compiled object files and external libraries (like standard input/output libraries) to produce a single, self-contained executable file. It also resolves symbolic references between these files, ensuring calls to external functions point to the correct machine code addresses.
Marking scheme
1 mark: Combines multiple object files / pre-compiled library files into a single executable. 1 mark: Resolves external references / links function calls to their actual memory locations.
Question 5 · short_answer
2 marks
In assembly language, describe the difference between the mnemonic and the operand.
Show answer & marking schemeHide answer & marking scheme
Worked solution
In assembly language, instructions are divided into an opcode and operands. The mnemonic is the human-readable text abbreviation representing the opcode (e.g., ADD, SUB, LDR) which tells the CPU what operation to execute. The operand represents the parameter or argument for that instruction, which can be a literal data value, a register name, or a memory address.
Marking scheme
1 mark: Mnemonic represents the command/operation code/opcode (e.g., ADD, SUB). 1 mark: Operand represents the data value/register/address to be acted upon by the command.
Question 6 · short_answer
2 marks
State two roles of the Domain Name System (DNS) in the operation of the internet.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The Domain Name System (DNS) serves as the directory for the internet. Its main role is resolving user-friendly hostnames (like google.com) into numerical IP addresses needed by network devices. It does this via a hierarchical distributed database of name servers that handle client lookup queries and cache results for performance.
Marking scheme
1 mark for each valid role (maximum of 2): Translating/resolving domain names/URLs to IP addresses (or vice-versa); Storing/maintaining a distributed directory/database of domain name/IP pairings; Caching resolved addresses to speed up future requests; Routing lookup queries to other DNS servers when a record is not found locally.
Question 7 · short_answer
2 marks
Explain why asymmetric encryption is considered more secure for transmitting data over the internet than symmetric encryption.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Symmetric encryption relies on a single shared key for both encryption and decryption. If two parties want to communicate, they must exchange this key, which introduces a major security risk if intercepted. Asymmetric encryption resolves this 'key exchange' problem by using a public-private key pair. Since the private key is kept strictly secret by its owner and never transmitted, an attacker intercepting the public key or ciphertext cannot decrypt the message.
Marking scheme
1 mark: Symmetric encryption requires transmitting/exchanging a shared key, which can be intercepted. 1 mark: Asymmetric encryption keeps the decryption (private) key secret and never transmits it, eliminating the key exchange risk.
Question 8 · short_answer
2 marks
State two principles of the Data Protection Act (or General Data Protection Regulation / GDPR) that an organization must follow when processing personal data.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The Data Protection Act / GDPR sets out several key principles for organisations holding personal data. These include: 1. Lawfulness, fairness, and transparency; 2. Purpose limitation; 3. Data minimisation; 4. Accuracy; 5. Storage limitation; 6. Integrity and confidentiality (security); and 7. Accountability. Any two of these, or accurate descriptions of them, are correct.
Marking scheme
1 mark per valid principle stated (up to a maximum of 2 marks): Lawfulness, fairness, and transparency; Purpose limitation (only collected for specified/legitimate reasons); Data minimisation (only collect what is necessary); Accuracy (must be kept up to date); Storage limitation (not kept for longer than necessary); Integrity and confidentiality / processed securely; Accountability (must take responsibility for how data is handled).
Question 9 · short_answer
2 marks
Describe one key difference between paging and segmentation in memory management.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Paging divides physical memory into fixed-sized blocks called pages, which do not necessarily align with the logical structure of a program. In contrast, segmentation divides memory into variable-sized, logical sections (such as subroutines, procedures, or data structures) based on the structure of the code.
Marking scheme
1 mark: Identify that pages are of a fixed size whereas segments are of variable size. 1 mark: Identify that paging is a physical division of memory whereas segmentation is a logical division based on the program's structure.
Question 10 · short_answer
2 marks
State two actions that the CPU takes when an interrupt of higher priority than the current task is detected at the end of a Fetch-Decode-Execute cycle.
Show answer & marking schemeHide answer & marking scheme
Worked solution
When a higher-priority interrupt is detected at the end of a cycle, the CPU first saves the contents of its registers (including the Program Counter) onto the stack to preserve the state of the interrupted program. It then loads the start address of the corresponding Interrupt Service Routine (ISR) into the Program Counter to begin executing the interrupt handler.
Marking scheme
Award 1 mark per correct action listed (max 2): - Saves the current state of registers/CPU (onto the stack). - Suspends execution of the currently running program. - Loads the address of the Interrupt Service Routine (ISR) into the Program Counter (PC). - Sets the CPU status to service the interrupt.
Question 11 · short_answer
2 marks
Explain the role of a Domain Name System (DNS) server when a user enters a URL into their web browser.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The DNS server acts like an address book. It receives the domain name (URL) requested by the client's browser and looks up its database to find the matching IP address. This IP address is then sent back to the client's browser so that it can establish a direct connection to the host server.
Marking scheme
1 mark: Translates / looks up / maps a domain name (or URL) into its corresponding IP address. 1 mark: Sends this IP address back to the client/browser so it can locate, route packets to, or connect to the host server.
Question 12 · short_answer
2 marks
Explain why floating-point numbers are stored in a normalized form.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Normalization ensures that there is only one unique representation for each real number (eliminating redundant representations and simplifying arithmetic comparisons). It also maximizes precision by ensuring that the most significant bits of the mantissa are used to represent the value, rather than wasting bits on leading zeros or ones.
Marking scheme
1 mark: To provide a unique / single representation for each number (to make comparisons/arithmetic simpler). 1 mark: To maximize precision / accuracy / make the most efficient use of bits.
Question 13 · short_answer
2 marks
An employee uses their company credentials to access a database containing confidential client information, which they are not authorized to view. State the specific offence under the Computer Misuse Act 1990 that has been committed, and justify your answer.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The employee has committed the offence of 'Unauthorised access to computer material' (Section 1 of the Computer Misuse Act 1990). Even though they have legitimate credentials to the company system, they did not have authorization to access or view this specific confidential client database, making their access intentional and unauthorised.
Marking scheme
1 mark: Identifies 'Unauthorised access to computer material' (accept Section 1 offence). 1 mark: Justification stating that access was intentional and they did not have the specific permission/authorization to view that database/material.
Question 14 · short_answer
2 marks
Describe how a search engine spider (crawler) indexes the World Wide Web.
Show answer & marking schemeHide answer & marking scheme
Worked solution
A search engine crawler (or spider) traverses the web by starting from a seed list of known URLs. It downloads and parses the content of each webpage, extracting the text, metadata, and keywords to build an index. It also extracts hyperlinks found on those pages and adds them to a queue to visit next, mapping the web recursively.
Marking scheme
1 mark: For stating that it downloads/parses pages to extract keywords/metadata/content and adds this to an index database. 1 mark: For stating that it follows hyperlinks on the pages to discover/traverse new URLs (building a queue of pages to visit next).
Question 15 · short_answer
2 marks
State one key operational difference between hashing and symmetric encryption.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Hashing is a one-way cryptographic function, meaning that once data is hashed, it cannot be mathematically reversed to recover the original plaintext. Symmetric encryption, however, is a two-way process where the encrypted ciphertext can be decrypted back into its original plaintext using the correct shared key.
Marking scheme
1 mark: Hashing is a one-way/irreversible process whereas encryption is a two-way/reversible process. 1 mark: Encryption requires a key to decrypt the ciphertext back to plaintext, whereas hashing does not use a key for decryption (or is designed to be mathematically irreversible).
Question 16 · structured_technical
4 marks
Describe the steps of the Fetch phase of the Fetch-Decode-Execute cycle, making explicit reference to the Program Counter (PC), Memory Address Register (MAR), Memory Data Register (MDR), and Current Instruction Register (CIR).
Show answer & marking schemeHide answer & marking scheme
Worked solution
The Fetch-Decode-Execute cycle begins with the Fetch phase. First, the CPU copies the address of the next instruction from the PC to the MAR. Next, the PC is incremented so it points to the address of the following instruction. The memory controller then reads the instruction from the memory location stored in the MAR, and loads this instruction into the MDR. Finally, the instruction is transferred from the MDR to the CIR, where it will be decoded in the next phase.
Marking scheme
1 mark: Copying the memory address of the next instruction from the PC to the MAR. 1 mark: Incrementing the PC to point to the next instruction. 1 mark: Fetching the instruction from the memory location in the MAR and loading it into the MDR. 1 mark: Copying the instruction from the MDR to the CIR.
Question 17 · structured_technical
4 marks
Memory management is a key function of an operating system. Describe two differences between paging and segmentation. State one issue that can occur with segmentation that does not occur with paging.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Paging divides physical memory and virtual memory into fixed-size blocks called pages, which are mapped to page frames. Segmentation divides memory into variable-sized logical units called segments, which match the structure of the program (e.g., individual functions, objects, or namespaces). Because pages are fixed-size, paging can suffer from internal fragmentation (wasted space within a page), but not external fragmentation. Segmentation can suffer from external fragmentation, where free memory is split into tiny, non-contiguous blocks that are too small to house any new variable-sized segment.
Marking scheme
Max 2 marks for differences: 1 mark for stating paging uses fixed-size blocks whereas segmentation uses variable-size blocks. 1 mark for stating paging is a physical division of memory whereas segmentation is a logical division. Max 2 marks for the issue: 1 mark for identifying external fragmentation. 1 mark for explaining that because segments are variable-size, removing and loading them leaves non-contiguous gaps of unused memory that are too small to fit new segments.
Question 18 · structured_technical
4 marks
Explain how asymmetric encryption (using public and private keys) can be used to send a message that is both confidential (only the intended recipient can read it) and authentic (proving it came from the sender).
Show answer & marking schemeHide answer & marking scheme
Worked solution
For confidentiality, the sender encrypts the message using the recipient's public key. Since only the recipient holds the corresponding private key, only they can decrypt and read it. For authenticity, the sender first hashes the message and encrypts the hash with their own private key to create a digital signature. The recipient decrypts this signature using the sender's public key. If the decrypted hash matches the hash of the received message, it guarantees the message was sent by the owner of the private key (the sender) and has not been altered.
Marking scheme
1 mark: Confidentiality is achieved by encrypting the message with the recipient's public key. 1 mark: Only the recipient's private key can decrypt the message. 1 mark: Authenticity is achieved by the sender encrypting the message hash/digital signature with their own private key. 1 mark: The recipient decrypts this signature using the sender's public key to verify identity/integrity.
Question 19 · structured_technical
4 marks
When a user enters a URL such as https://www.ocr.org.uk into a web browser, the Domain Name System (DNS) is used. Explain the step-by-step process of how the browser uses the DNS to obtain the IP address of the server hosting the website.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The browser first checks its local cache to see if it already knows the IP address of the requested domain name. If it is not found, the browser queries a DNS recursive resolver (usually provided by the ISP). If the recursive resolver does not have the address cached, it queries the DNS root name server, which points it to the Top-Level Domain (TLD) server (in this case, for '.uk'). The TLD server then points the resolver to the authoritative name server for 'ocr.org.uk'. The authoritative server returns the specific IP address back to the resolver, which sends it to the browser and caches it for future use.
Marking scheme
1 mark: Browser checks local cache or queries the recursive DNS resolver. 1 mark: Recursive resolver queries a Root Name Server to find the TLD server. 1 mark: Resolver queries the TLD server (e.g., '.uk') to locate the Authoritative Name Server. 1 mark: Authoritative Name Server returns the exact IP address to the resolver/browser.
Question 20 · structured_technical
4 marks
Simplify the following Boolean expression using Boolean algebra laws: \(Q = \neg(\neg A \cdot B) \cdot \neg(A \cdot \neg B)\). Show your working and state the laws used.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Step 1: Apply De Morgan's Law to both terms. \(\neg(\neg A \cdot B) = \neg(\neg A) + \neg B = A + \neg B\) and \(\neg(A \cdot \neg B) = \neg A + \neg(\neg B) = \neg A + B\). This gives \(Q = (A + \neg B) \cdot (\neg A + B)\). Step 2: Use the Distributive Law to expand the brackets. \(Q = A \cdot \neg A + A \cdot B + \neg B \cdot \neg A + \neg B \cdot B\). Step 3: Apply the Complement Law. Since \(A \cdot \neg A = 0\) and \(\neg B \cdot B = 0\), the expression becomes \(Q = 0 + A \cdot B + \neg A \cdot \neg B + 0\). Step 4: Apply the Identity Law to obtain the final simplified expression: \(Q = A \cdot B + \neg A \cdot \neg B\).
Marking scheme
1 mark: Correctly applying De Morgan's Law to rewrite the expression as \((A + \neg B) \cdot (\neg A + B)\). 1 mark: Correctly expanding the terms using the Distributive Law to get \(A\neg A + AB + \neg A\neg B + B\neg B\). 1 mark: Applying the Complement Law to reduce \(A\neg A\) and \(B\neg B\) to 0. 1 mark: Arriving at the final correct simplified expression: \(A \cdot B + \neg A \cdot \neg B\) (accept XNOR equivalent).
Question 21 · structured_technical
4 marks
Explain the requirements a database relation must meet to be in Third Normal Form (3NF). Your answer should describe the transition from Second Normal Form (2NF) to Third Normal Form (3NF).
Show answer & marking schemeHide answer & marking scheme
Worked solution
First, the database table must satisfy all requirements of Second Normal Form (2NF), meaning it has no partial dependencies (every non-key attribute is fully dependent on the entire primary key). Second, to achieve 3NF, there must be no transitive dependencies. A transitive dependency occurs when a non-key attribute is dependent on another non-key attribute. To resolve this, the non-key attribute that depends on another non-key attribute is removed and placed in a new table, with the determining attribute becoming the primary key in that new table and remaining as a foreign key in the original table.
Marking scheme
1 mark: Stating the table must already be in Second Normal Form (2NF). 1 mark: Explaining that there must be no transitive dependencies (or that all non-key attributes must only depend on the primary key). 1 mark: Explaining how to resolve a transitive dependency by moving the dependent non-key attributes to a new table. 1 mark: Specifying that the determining attribute becomes the primary key of the new table and remains as a foreign key in the original table.
Question 22 · structured_technical
4 marks
Assembly language utilizes different addressing modes to access data in memory. Explain the difference between direct addressing and indexed addressing. Your answer should explain how the operand is used to determine the actual memory address of the data in each case.
Show answer & marking schemeHide answer & marking scheme
Worked solution
In direct addressing, the operand specifies the exact physical memory address of the data being accessed (e.g., LDA 200 loads data from memory address 200 directly). No calculations are performed. In indexed addressing, the effective address is computed dynamically. The CPU adds the operand's value (acting as a base address) to the contents of the Index Register (IX) to find the final target address. This allows programs to step through sequential data structures, like arrays, by incrementing the index register.
Marking scheme
1 mark: Explains that in direct addressing, the operand is the exact memory address where the target data is located. 1 mark: Identifies that direct addressing is static / requires no calculations to find the address. 1 mark: Explains that in indexed addressing, the final address is calculated by adding the operand to the value in the Index Register. 1 mark: Mentions that indexed addressing is useful for iterating through sequential data structures like arrays.
Question 23 · structured_technical
4 marks
A social media company stores a large amount of personal data about its users, including names, dates of birth, and private messages. With reference to the Data Protection Act 2018 (which incorporates GDPR), identify and explain two principles that the social media company must follow when handling this user data.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The Data Protection Act 2018 sets out several key data protection principles. One principle is 'Data minimisation', meaning the company must only collect and process data that is strictly necessary for providing the social media platform (e.g. not asking for unnecessary secondary personal details). Another principle is 'Storage limitation', which requires that personal data must not be kept longer than needed. Once an account is deactivated or the data is no longer required, it must be deleted. Other valid principles include Accuracy, Lawfulness, fairness and transparency, Integrity and confidentiality (security), and Purpose limitation.
Marking scheme
1 mark: Identifying a valid DPA 2018 principle (e.g., Data minimisation, Storage limitation, Accuracy, Security, etc.). 1 mark: Explaining this principle accurately in context. 1 mark: Identifying a second valid DPA 2018 principle. 1 mark: Explaining the second principle accurately in context.
Question 24 · structured_technical
4 marks
Pipelining is a technique used in modern processors to improve execution speed. However, certain instructions can disrupt the pipeline, requiring it to be flushed. Explain how conditional branching causes a pipeline flush, and describe one method used by processors to minimize this performance penalty.
Show answer & marking schemeHide answer & marking scheme
Worked solution
1. A conditional branch instruction introduces uncertainty because the processor cannot know which instruction to fetch next until the branch condition is evaluated in the execution stage. 2. To keep the pipeline full, the processor speculatively fetches instructions from the sequential path. 3. If the branch is taken, the speculatively fetched instructions are incorrect and must be discarded, which is called flushing the pipeline. This introduces empty cycles into the pipeline. 4. To minimize this penalty, modern processors use branch prediction algorithms to predict the outcome of the branch, allowing them to fetch the correct instructions with high probability, or they pre-fetch instructions from both possible execution paths.
Marking scheme
Max 4 marks in total: 1 mark for explaining that the next instruction to fetch depends on a condition that is not resolved until later in the pipeline; 1 mark for explaining that the processor speculatively fetches/decodes subsequent instructions to keep the pipeline full; 1 mark for explaining that if the prediction/sequential assumption is wrong, those incorrect instructions must be discarded (flushed), wasting CPU cycles; 1 mark for describing a mitigation method (such as branch prediction to guess the path, or speculative execution / pre-fetching both paths).
Question 25 · structured_technical
4 marks
Describe how a data payload is encapsulated as it travels down the layers of the TCP/IP protocol stack, from the Application layer to the Network (Internet) layer.
Show answer & marking schemeHide answer & marking scheme
Worked solution
1. At the Application layer, the application-specific data (the payload) is generated (e.g., an HTTP request). 2. This data is passed down to the Transport layer, where it is split into segments. A Transport layer header (containing source and destination port numbers and sequence numbers) is prepended to each segment. 3. The segment is then passed to the Network (Internet) layer. The Network layer adds its own header (containing source and destination IP addresses) to create an IP packet. 4. Each layer encapsulates the data from the layer above by wrapping it with control headers containing the necessary routing and connection parameters.
Marking scheme
Max 4 marks in total: 1 mark for Application layer generating raw data/payload; 1 mark for Transport layer adding a header containing port numbers / sequence numbers, encapsulating the payload into segments; 1 mark for Network (Internet) layer adding an IP header containing source/destination IP addresses, encapsulating the segment into packets; 1 mark for clear explanation of the concept of encapsulation (i.e., higher-layer data becomes the payload of the lower-layer protocol, which prepends control headers).
Question 26 · structured_technical
4 marks
A computer uses a floating-point system with an 8-bit normalized mantissa and a 4-bit exponent, both in two's complement. The binary representation of a number in this format is: Mantissa: 01110000, Exponent: 0011. Show the step-by-step working required to convert this binary representation into its denary equivalent.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Step 1: Identify the mantissa and place the binary point after the first bit. The mantissa is positive (starts with 0) and represents \( 0.1110000_2 \). Convert this to denary: \( 0.5 + 0.25 + 0.125 = 0.875 \). Step 2: Convert the exponent \( 0011_2 \) to denary. Since it is positive, it equals \( +3 \). Step 3: Apply the exponent to the mantissa: \( 0.875 \times 2^3 \) or shift the binary point 3 places to the right: \( 0111.0000_2 \). Step 4: Convert \( 0111.0000_2 \) to denary, which gives \( 7 \) (or \( 7.0 \)).
Marking scheme
Max 4 marks in total: 1 mark for correctly identifying the mantissa value as \( 0.111_2 \) or denary \( 0.875 \) (or \( 7/8 \)); 1 mark for correctly converting the exponent \( 0011 \) to denary \( +3 \); 1 mark for showing correct application of the exponent (e.g., shifting binary point 3 places right to get \( 0111_2 \) or showing the calculation \( 0.875 \times 8 \)); 1 mark for correct final denary answer of \( 7 \) (accept \( 7.0 \)).
Question 27 · structured_technical
4 marks
Operating systems employ memory management techniques to optimize the use of physical RAM. Describe two distinct differences between paging and segmentation.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Difference 1: Paging divides physical and logical memory into fixed-size blocks called pages/page frames, whereas segmentation divides memory into variable-sized, logical blocks called segments that match the logical structure of the program (e.g., functions, stack, variables). Difference 2: Paging is handled entirely by the Operating System and MMU without any awareness or design input from the programmer (physical division), whereas segmentation is a logical division that can be influenced by how the code/compiler organizes different modules and components of a program.
Marking scheme
Max 4 marks in total (2 marks per fully explained difference): 1 mark for stating paging uses fixed-size blocks AND 1 mark for contrasting with segmentation using variable-sized logical blocks; 1 mark for stating paging is a physical division (invisible to programmer/handled by hardware) AND 1 mark for contrasting with segmentation being a logical division (reflective of program structures like functions/objects).
Question 28 · essay_evaluation
10 marks
A university's high-performance research computing cluster runs complex simulations that require massive amounts of RAM. The systems administrator is configuring the operating system's memory management scheme.
*Discuss the differences between paging and segmentation as memory management techniques. Evaluate the use of virtual memory in this high-performance computing environment, discussing its benefits and potential drawbacks. (10 marks)
Show answer & marking schemeHide answer & marking scheme
Worked solution
Key Technical Points:
Paging vs Segmentation: - Paging: Divides physical memory and programs into fixed-size blocks called pages (virtual memory) and page frames (physical memory). It is a physical division and does not consider the logical structure of the program. Page tables map virtual addresses to physical addresses. Can lead to internal fragmentation. - Segmentation: Divides programs into logical, variable-sized blocks called segments (e.g., functions, stack, arrays). It is a logical division based on how the program is written. Segment tables map segments to physical memory, storing start address and limit size. Can lead to external fragmentation.
Virtual Memory in HPC (High-Performance Computing): - How it works: Uses secondary storage (SSDs/HDDs) as an extension of RAM when physical RAM is full. Swaps inactive pages/segments to disk and active ones in. - Benefits: Allows extremely large simulations to run even if they exceed physical RAM capacity, preventing out-of-memory crashes. Allows multi-tasking and efficient allocation of resources. - Drawbacks: Secondary storage is orders of magnitude slower than RAM. Frequent swapping (thrashing) severely degrades performance, making high-performance clusters highly inefficient. Disk read/write overheads reduce CPU utilization for actual computing.
Evaluation & Synthesis: For high-performance computing, minimizing virtual memory usage is critical. While it provides a safety net to prevent crashes, administrators should optimize code or upgrade RAM to avoid thrashing, which defeats the purpose of high-performance computing.
Marking scheme
Level 3 (8-10 marks): - Candidate provides a thorough and detailed discussion of both paging and segmentation, highlighting several key technical differences. - Comprehensive evaluation of virtual memory in an HPC context, covering both benefits and severe drawbacks (thrashing, performance degradation). - The answer is well-structured, uses accurate technical terminology, and presents a clear, reasoned conclusion.
Level 2 (5-7 marks): - Candidate provides a reasonable explanation of both paging and segmentation, identifying some differences. - Good discussion of virtual memory, explaining how it works and listing some advantages/disadvantages, though the link to HPC may not be fully developed. - The answer is mostly structured and contains technical terminology, with few errors.
Level 1 (1-4 marks): - Candidate shows limited understanding, perhaps defining only paging or segmentation, or confusing the two. - Superficial mention of virtual memory with little or no reference to the context. - Information is basic, unstructured, and lacks technical depth.
Question 29 · essay_evaluation
10 marks
An international logistics company is setting up a new WAN (Wide Area Network) to connect multiple regional warehouses to its central inventory database. Database transactions must be transmitted reliably and without corruption.
*Discuss the roles of the different layers of the TCP/IP stack in ensuring the reliable and accurate transmission of database queries and responses across this wide area network. Evaluate the importance of protocols at the Transport and Network layers in preventing data loss and congestion. (10 marks)
Show answer & marking schemeHide answer & marking scheme
Worked solution
Key Technical Points:
Layers of the TCP/IP Stack & Their Roles: - Application Layer: Interacts with the database management software. Uses protocols to format queries/responses. - Transport Layer: Establishes end-to-end connection and splits data into packets/segments. Uses port numbers to direct data. TCP ensures reliable delivery through sequence numbers, acknowledgements, and retransmissions. - Network / Internet Layer: Responsible for routing packets across the WAN from source to destination. Adds source and destination IP addresses to packets. Uses routing protocols to find the most efficient path. - Link / Network Interface Layer: Handles the physical transmission of data bits over the physical medium. Adds MAC addresses to frames and performs error checking (e.g., CRC) on the physical link.
Importance of Transport and Network Layer Protocols in WAN: - Transport Layer (TCP): Essential for database transactions where 100% accuracy is required. Uses a three-way handshake, sliding window/flow control to prevent receiver overwhelm, and sequence numbers to reassemble packets in order. - Network Layer (IP and Routing Protocols): Handles network congestion by dynamically routing around slow or broken nodes in the WAN.
Evaluation & Synthesis: Without the TCP/IP stack layers working cohesively, the WAN would experience high packet loss, out-of-order packets, and slow performance, rendering database operations completely unreliable and leading to data inconsistency.
Marking scheme
Level 3 (8-10 marks): - Candidate provides a comprehensive explanation of all four layers of the TCP/IP stack, clearly linking each layer's role to the scenario. - Detailed evaluation of the specific importance of Transport (TCP) and Network (IP/routing) layers, explaining mechanisms such as sequence numbers, acknowledgements, and dynamic routing. - The response is exceptionally well-structured, uses precise technical terminology, and offers a coherent conclusion.
Level 2 (5-7 marks): - Candidate describes most of the TCP/IP stack layers, with reasonable accuracy. - Discusses the roles of the Transport and Network layers, mentioning key aspects like TCP reliability or routing, though some technical details may be omitted. - The response has some structure and uses appropriate terminology.
Level 1 (1-4 marks): - Candidate shows a limited understanding of the TCP/IP stack, perhaps confusing layers or only explaining one or two layers. - Mentions reliability or routing superficially, with minimal reference to the scenario. - The answer lacks technical depth and structure.
Question 30 · essay_evaluation
10 marks
A startup company is developing a health-tracking mobile app called 'PulsePath' which tracks users' live GPS location, daily heart rate, and personal medical history. The app also features a social feed allowing users to share their fitness achievements.
*Discuss how the Data Protection Act 2018 (implementing GDPR) and the Computer Misuse Act 1990 impact the design, development, and operation of 'PulsePath'. Evaluate the measures the developers must take to remain legally compliant while maintaining a highly engaging user experience. (10 marks)
Show answer & marking schemeHide answer & marking scheme
Worked solution
Key Technical Points:
Data Protection Act 2018 (GDPR) Impacts: - Personal and Sensitive Data: Live GPS locations, heart rate, and medical histories are classified as high-risk, sensitive personal data (special category data). - Principles to follow: 1. Lawfulness, fairness, and transparency: Users must give explicit, active consent (opt-in) for tracking location and medical data. The privacy policy must clearly state what is collected. 2. Purpose limitation: Data must only be used for tracking health/social sharing, not sold without explicit consent. 3. Data minimisation: Only collect essential health and location data. 4. Integrity and confidentiality (Security): Data must be strongly encrypted during transit (HTTPS/TLS) and at rest. 5. Rights of data subjects: Users have the 'right to be forgotten' and 'right of access'.
Computer Misuse Act 1990 Impacts: - Prevention of unauthorized access: Developers must secure backend APIs and databases (e.g., using strong hashing, MFA, and penetration testing) to prevent hacking/data breaches under Section 1. - Prevention of unauthorized modification: Developers must ensure users cannot modify other users' data (preventing IDOR/parameter tampering) under Section 3.
Balancing Compliance and Engagement: - Frictionless Consent: Use interactive, easy-to-read onboarding screens that explain the benefits of sharing GPS (e.g., 'Track your running route!') to encourage opting in instead of presenting long legal text. - Privacy by Design: Incorporate easy privacy toggles in the UI (e.g., public vs. friends-only vs. private) to build user trust and engagement.
Marking scheme
Level 3 (8-10 marks): - Candidate shows a comprehensive understanding of both the Data Protection Act 2018 (GDPR) and the Computer Misuse Act 1990, precisely applying their principles to the scenario. - Detailed evaluation of how to achieve compliance while maintaining user engagement. - The response is exceptionally well-structured, uses accurate legal and technical terminology, and presents a balanced evaluation.
Level 2 (5-7 marks): - Candidate discusses both acts, identifying relevant principles of the Data Protection Act and key aspects of the Computer Misuse Act. - Some application of the legislation to the scenario is present, with practical compliance suggestions, though the connection to user engagement may be brief. - The structure is logical, and mostly accurate technical terms are used.
Level 1 (1-4 marks): - Candidate displays a basic understanding of computer law, but may confuse the acts or speak in very general terms. - Minimal or no application to the scenario or to the dual requirement of compliance and engagement. - Information is poorly structured and lacks specific detail.
Question 31 · algorithm_completion
5 marks
A developer is implementing a singly linked list in an array called `list` where each node is an instance of a class with attributes `value` and `next`.
The global variable `start` stores the index of the first node of the list. The global variable `freeList` stores the index of the first node in the list of free (empty) nodes. Both `start` and `freeList` are initialized to `-1` when their respective lists are empty.
The following pseudocode is intended to insert a new item at the start of the linked list. Complete the pseudocode by identifying the correct code to fill in the blanks [A] to [E].
``` procedure insertAtStart(newItem) if freeList == -1 then print("List is full") else newNodeIndex = freeList freeList = [ A ]
list[newNodeIndex].value = [ B ] list[newNodeIndex].next = [ C ]
[ D ] = [ E ] endif endprocedure ```
Show answer & marking schemeHide answer & marking scheme
Worked solution
To insert a node at the start of a singly linked list using an array of nodes: 1. We first retrieve the index of the next available free node: `newNodeIndex = freeList`. 2. We then update the `freeList` pointer to point to the next free node, which is stored in `list[freeList].next` (or equivalently `list[newNodeIndex].next`). This gives us [A]. 3. We populate the value of the new node with the item being inserted: `list[newNodeIndex].value = newItem`. This gives us [B]. 4. Since this node will become the new starting node, its `next` pointer must point to what was previously the first node in the list, stored in `start`. Thus, `list[newNodeIndex].next = start`. This gives us [C]. 5. Finally, we update the `start` pointer of the linked list to point to our newly created node: `start = newNodeIndex`. This gives us [D] = [E].
Marking scheme
1 mark for each correct blank: - [A]: list[freeList].next OR list[newNodeIndex].next - [B]: newItem - [C]: start - [D]: start - [E]: newNodeIndex
Note for [D] and [E]: They must be in the exact order `start = newNodeIndex` because writing `newNodeIndex = start` would incorrectly overwrite the local variable containing the index of the new node instead of updating the global head pointer.
Question 32 · algorithm_completion
5 marks
An algorithm is required to check whether parentheses in an algebraic expression are correctly balanced.
A Stack object `s` is used, which has the following methods: - `s.push(item)`: adds `item` to the top of the stack. - `s.pop()`: removes and returns the top item. - `s.isEmpty()`: returns `True` if the stack is empty, otherwise `False`.
Complete the function `isBalanced` by identifying the correct code to fill in the blanks [A] to [E].
``` function isBalanced(expression) s = new Stack() for i = 0 to expression.length - 1 char = expression[i] if char == "(" then [ A ] else if char == ")" then if [ B ] then return [ C ] else [ D ] endif endif next i
return [ E ] endfunction ```
Show answer & marking schemeHide answer & marking scheme
Worked solution
To check for balanced parentheses: 1. Every time we encounter an opening parenthesis `(`, we push it onto the stack: `s.push(char)` or `s.push("(")`. This gives us [A]. 2. Every time we encounter a closing parenthesis `)`, we check if there is a corresponding opening parenthesis on the stack. If the stack is empty (`s.isEmpty()`), it means there is an unmatched closing parenthesis, so we immediately return `False`. This gives us [B] and [C]. 3. If the stack is not empty, we pop the corresponding opening parenthesis from the stack: `s.pop()`. This gives us [D]. 4. Once the loop finishes processing the expression, any unmatched opening parentheses would still remain on the stack. Thus, the expression is balanced if and only if the stack is now completely empty. Returning `s.isEmpty()` will return `True` if balanced, or `False` if there are leftover unclosed opening parentheses. This gives us [E].
Marking scheme
1 mark for each correct blank: - [A]: s.push(char) OR s.push("(") - [B]: s.isEmpty() OR s.isEmpty() == True OR s.isEmpty() == true - [C]: False OR false - [D]: s.pop() - [E]: s.isEmpty() OR s.isEmpty() == True OR s.isEmpty() == true
Paper 2: Algorithms and Programming
Answer all questions. Calculators are not allowed. Section A contains structured questions. Section B contains context-based algorithmic design questions.
25 Question · 111 marks
Question 1 · short_answer
2 marks
Describe the main difference between passing a parameter by value and passing it by reference.
Show answer & marking schemeHide answer & marking scheme
Worked solution
When a parameter is passed by value, a copy of the actual data is created in a new memory location for the subroutine. Any modifications made to this parameter inside the subroutine do not affect the original variable. Conversely, when passed by reference, the memory address of the original variable is passed. This means any modifications made to the parameter within the subroutine are made directly to the original variable's memory location, permanently changing its value.
Marking scheme
1 mark: Explain that passing by value uses a copy of the variable and does not affect the original variable. 1 mark: Explain that passing by reference uses the memory address of the original variable, meaning modifications affect the original variable.
Question 2 · short_answer
2 marks
Explain the difference between a tree and a graph data structure.
Show answer & marking schemeHide answer & marking scheme
Worked solution
A tree is a specialized, restricted type of graph. It must be hierarchical, connected, and acyclic (containing no loops), meaning there is exactly one unique path between any two nodes, and it has a single root node. A graph is a more general structure consisting of vertices connected by edges; it can be directed or undirected, can contain cycles (loops), can be disconnected, and does not have a predefined hierarchical root structure.
Marking scheme
1 mark: Define tree characteristics (e.g., acyclic, hierarchical, has a root node, or one unique path between nodes). 1 mark: Define graph characteristics (e.g., can have cycles, can be disconnected, has no root node, or is non-hierarchical).
Question 3 · short_answer
2 marks
State the best-case time complexity of an optimized Bubble Sort algorithm on an array of \(n\) elements, and describe the condition under which this best-case occurs.
Show answer & marking schemeHide answer & marking scheme
Worked solution
An optimized Bubble Sort uses a flag to check if any swaps were made during a pass. If no swaps are made on the first pass, the algorithm terminates early. This yields a best-case time complexity of \(O(n)\). This best case only occurs when the input array is already in the correct sorted order.
Marking scheme
1 mark: State the best-case time complexity is \(O(n)\) (or linear). 1 mark: State that this occurs when the array is already sorted.
Question 4 · short_answer
2 marks
State two potential drawbacks of implementing concurrency in a complex software application.
Show answer & marking schemeHide answer & marking scheme
Worked solution
While concurrency allows multiple tasks to execute in overlapping time periods, it introduces significant challenges. These include race conditions, where multiple threads attempt to write to shared data simultaneously; deadlocks, where threads are blocked waiting for resources held by each other; and increased difficulty in testing and debugging because the execution order is non-deterministic.
Marking scheme
1 mark: Identify race conditions or deadlocks. 1 mark: Identify increased complexity in writing, testing, or debugging concurrent code.
Question 5 · short_answer
2 marks
Describe why identifying preconditions is important when designing a subroutine.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Preconditions define the constraints and requirements that must be met before a subroutine can execute successfully (e.g., passing a positive integer). Identifying these is important because it establishes a clear contract between the calling code and the subroutine. It eliminates the need for the subroutine to perform redundant checks on its inputs, simplifying its code, and ensures that the calling program handles validation, making the entire system more robust and easier to debug.
Marking scheme
1 mark: Explains that it establishes a contract/requirements for the calling program (e.g., input requirements, state of system). 1 mark: Explains that it prevents errors, simplifies the subroutine code (no redundant checks needed), or makes code more reusable/robust.
Question 6 · short_answer
2 marks
In the context of heuristic search algorithms, such as A* search, state what a heuristic is and explain its purpose.
Show answer & marking schemeHide answer & marking scheme
Worked solution
In search algorithms, a heuristic is an approximate rule-of-thumb or mathematical estimate of the cost or distance from the current node to the destination. Its purpose is to prioritize the order in which nodes are explored, steering the search towards the most promising paths. This drastically reduces the number of states that need to be evaluated compared to exhaustive methods like Dijkstra's, making the search much faster and more efficient.
Marking scheme
1 mark: State that a heuristic is an estimate of the remaining cost/distance to the goal. 1 mark: Explain that its purpose is to optimize/speed up the search process by prioritizing more promising paths.
Question 7 · short_answer
2 marks
State what is meant by 'caching' and explain how it improves the performance of a system.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Caching refers to the temporary storage of recently or frequently accessed data in high-speed memory (such as CPU cache, RAM, or dedicated cache servers). It improves system performance because retrieving data from a cache is significantly faster than fetching it from slower main memory, secondary storage (like a hard disk), or over a network. This reduces latency, saves bandwidth, and decreases CPU overhead.
Marking scheme
1 mark: Definition of caching as storing frequently/recently accessed data in a fast, temporary storage location. 1 mark: Explains that it improves performance by reducing retrieval latency/times, avoiding slower fetches from secondary storage or networks.
Question 8 · short_answer
2 marks
Simplify the Boolean expression \(A \cdot (\neg A + B)\) using Boolean algebraic laws. Show your working.
Show answer & marking schemeHide answer & marking scheme
Worked solution
We apply the Distributive Law first: \(A \cdot (\neg A + B) = (A \cdot \neg A) + (A \cdot B)\). Using the Complement Law, we know that \(A \cdot \neg A = 0\). Therefore, the expression becomes: \(0 + (A \cdot B)\). Using the Identity Law, \(0 + (A \cdot B)\) simplifies to \(A \cdot B\) (or simply \(AB\)).
Marking scheme
1 mark: Apply the distributive law correctly to get \((A \cdot \neg A) + (A \cdot B)\). 1 mark: Identify that \(A \cdot \neg A = 0\) to get the final correct simplified answer of \(A \cdot B\) (or \(AB\)).
Question 9 · short_answer
2 marks
Explain two benefits of specifying preconditions when designing a subroutine.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Preconditions act as a contract between the calling code and the subroutine. By specifying what must be true before execution (e.g., input must be a positive integer), the programmer writing the subroutine does not have to write validation code inside the subroutine, reducing code complexity and execution overhead. It also ensures clear documentation, making it easier for teams to integrate components and isolate bugs.
Marking scheme
1 mark per valid benefit explained (maximum 2 marks): - Saves development time / reduces code complexity as the subroutine does not need to duplicate input validation checks. - Simplifies debugging and testing by providing a clear 'contract' / documentation of what inputs are valid. - Restricts the scope of inputs, making the subroutine easier to write and design.
Question 10 · short_answer
2 marks
A circular queue of maximum size 8 is implemented using a 1D array. Describe how the modulo operator is used when adding an item to this queue.
Show answer & marking schemeHide answer & marking scheme
Worked solution
When a new element is added (enqueued), the tail pointer must point to the next insertion index. In a circular queue, the modulo operator wraps the pointer back to the beginning of the array if it exceeds the boundary. The operation tail = (tail + 1) MOD 8 ensures that when tail is at index 7 (the end of the array), adding an item moves the tail pointer to (7 + 1) MOD 8 = 0, reusing empty spaces created when elements were dequeued.
Marking scheme
Max 2 marks: - 1 mark: For explaining that it wraps the pointer back to the start (index 0) of the array when it reaches the end of the array. - 1 mark: For identifying that this allows empty memory spaces (from dequeued items) at the start of the array to be reused.
Question 11 · structured_algorithm_trace
5 marks
A recursive function process is defined below:
function process(items, n) if n <= 0 then return 0 elseif items[n-1] % 2 == 0 then return items[n-1] + process(items, n-1) else return process(items, n-1) - items[n-1] endif endfunction
Trace the execution of process([3, 8, 5, 2], 4) by showing each recursive call and its return value. State the final returned value.
Show answer & marking schemeHide answer & marking scheme
Worked solution
The function execution is traced step-by-step as follows: 1. process([3, 8, 5, 2], 4): n = 4. items[3] is 2, which is even. Returns 2 + process(items, 3). 2. process([3, 8, 5, 2], 3): n = 3. items[2] is 5, which is odd. Returns process(items, 2) - 5. 3. process([3, 8, 5, 2], 2): n = 2. items[1] is 8, which is even. Returns 8 + process(items, 1). 4. process([3, 8, 5, 2], 1): n = 1. items[0] is 3, which is odd. Returns process(items, 0) - 3. 5. process([3, 8, 5, 2], 0): n = 0. Hits base case and returns 0.
Now we propagate the values back up the recursive call stack: - process(items, 1) = 0 - 3 = -3 - process(items, 2) = 8 + (-3) = 5 - process(items, 3) = 5 - 5 = 0 - process(items, 4) = 2 + 0 = 2
Consider the following algorithm that processes an integer input:
function analyze(num) count = 0 temp = num while temp > 0 digit = temp MOD 10 if digit MOD 3 == 0 then count = count + 1 endif temp = temp DIV 10 endwhile return count endfunction
Trace the execution of analyze(7392) by showing the state of the variables count, temp, and digit at each iteration. State the final returned value.
Show answer & marking schemeHide answer & marking scheme
Worked solution
We trace the variables through each iteration of the loop:
Initial state: num = 7392, count = 0, temp = 7392
- Iteration 1: digit = 7392 MOD 10 = 2 digit MOD 3 == 0 -> 2 MOD 3 == 2 (False), count remains 0 temp = 7392 DIV 10 = 739
- Iteration 2: digit = 739 MOD 10 = 9 digit MOD 3 == 0 -> 9 MOD 3 == 0 (True), count is incremented to 1 temp = 739 DIV 10 = 73
- Iteration 3: digit = 73 MOD 10 = 3 digit MOD 3 == 0 -> 3 MOD 3 == 0 (True), count is incremented to 2 temp = 73 DIV 10 = 7
- Iteration 4: digit = 7 MOD 10 = 7 digit MOD 3 == 0 -> 7 MOD 3 == 1 (False), count remains 2 temp = 7 DIV 10 = 0
Loop terminates because temp is no longer greater than 0. The final returned value of count is 2.
Marking scheme
1 mark: Correct initial values prior to loop (count = 0, temp = 7392). 1 mark: Correctly traces Iteration 1 (digit = 2, temp = 739, count = 0). 1 mark: Correctly traces Iteration 2 (digit = 9, temp = 73, count = 1). 1 mark: Correctly traces Iteration 3 (digit = 3, temp = 7, count = 2). 1 mark: Correctly traces Iteration 4 (digit = 7, temp = 0) and states the final returned value of 2.
Question 13 · structured_algorithm_trace
5 marks
An array stack of size 5 is initialized with empty values. A pointer top is initialized to -1. The following procedures and functions are defined:
global stack[5] global top = -1
procedure push(val) if top < 4 then top = top + 1 stack[top] = val endif endprocedure
function pop() if top >= 0 then val = stack[top] top = top - 1 return val else return -1 endif endfunction
function performOps() push(12) push(24) push(36) a = pop() push(a + 4) push(15) b = pop() return b endfunction
Trace the execution of performOps() showing the values in the stack array, the value of top, and the return value of b.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Let's trace the execution of performOps() step-by-step:
1. Initial state: stack = [null, null, null, null, null], top = -1 2. push(12): top becomes 0, stack[0] = 12. stack = [12, null, null, null, null] 3. push(24): top becomes 1, stack[1] = 24. stack = [12, 24, null, null, null] 4. push(36): top becomes 2, stack[2] = 36. stack = [12, 24, 36, null, null] 5. a = pop(): stack[2] (value 36) is retrieved. top decrements to 1. a = 36. stack = [12, 24, 36, null, null] (logically popped, index 2 is now above top) 6. push(a + 4) -> push(40): top increments to 2, stack[2] is overwritten with 40. stack = [12, 24, 40, null, null] 7. push(15): top increments to 3, stack[3] = 15. stack = [12, 24, 40, 15, null] 8. b = pop(): stack[3] (value 15) is retrieved. top decrements to 2. b = 15. 9. return b: returns 15.
Marking scheme
1 mark: Correct state of top = 2 and stack contents [12, 24, 36, null, null] after first three pushes. 1 mark: Correctly identifies a = 36 and top decrements to 1 after pop(). 1 mark: Correctly identifies push(40) updates top to 2 and sets stack[2] = 40. 1 mark: Correctly identifies push(15) updates top to 3 and sets stack[3] = 15. 1 mark: Correctly identifies b = 15, top decrements to 2, and returns 15.
Question 14 · structured_algorithm_trace
5 marks
A programmer is tracing an ascending bubble sort algorithm. The list of integers to sort is A = [14, 3, 9, 12, 5]. The outer loop makes a single first pass through the array:
for i = 0 to len(A) - 2 if A[i] > A[i+1] then temp = A[i] A[i] = A[i+1] A[i+1] = temp endif next i
Trace the execution of this first pass, showing the comparisons and state of array A after each iteration of the loop. State the final state of array A after the first pass is complete.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Initial array state: A = [14, 3, 9, 12, 5]. The loop index i goes from 0 to 3 (since len(A) - 2 = 5 - 2 = 3):
- i = 0: Compares A[0] (14) and A[1] (3). Since 14 > 3 is True, they are swapped. Array A becomes: [3, 14, 9, 12, 5]
- i = 1: Compares A[1] (14) and A[2] (9). Since 14 > 9 is True, they are swapped. Array A becomes: [3, 9, 14, 12, 5]
- i = 2: Compares A[2] (14) and A[3] (12). Since 14 > 12 is True, they are swapped. Array A becomes: [3, 9, 12, 14, 5]
- i = 3: Compares A[3] (14) and A[4] (5). Since 14 > 5 is True, they are swapped. Array A becomes: [3, 9, 12, 5, 14]
After the first pass is complete, the final array state is [3, 9, 12, 5, 14].
Marking scheme
1 mark: Correct comparison of 14 and 3, resulting in array state [3, 14, 9, 12, 5]. 1 mark: Correct comparison of 14 and 9, resulting in array state [3, 9, 14, 12, 5]. 1 mark: Correct comparison of 14 and 12, resulting in array state [3, 9, 12, 14, 5]. 1 mark: Correct comparison of 14 and 5, resulting in array state [3, 9, 12, 5, 14]. 1 mark: Correctly concludes that the loop finishes and states the final correct array [3, 9, 12, 5, 14].
Question 15 · structured_algorithm_trace
5 marks
An array names contains the following sorted elements: [\"Aiden\", \"Chloe\", \"Ethan\", \"Grace\", \"Jack\", \"Lily\", \"Mason\", \"Olivia\"].
A binary search algorithm is used to search for the target \"Mason\":
low = 0 high = len(names) - 1 found = false while low <= high and found == false mid = (low + high) DIV 2 if names[mid] == target then found = true elseif names[mid] < target then low = mid + 1 else high = mid - 1 endif endwhile
Trace the execution of this search by showing the values of low, high, mid, and found at each iteration. State the final index where the target is found.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Initial state: low = 0, high = 7, found = false
- Iteration 1: mid = (0 + 7) DIV 2 = 3 names[3] is \"Grace\" Since \"Grace\" < \"Mason\" is True, low becomes mid + 1 = 4. found remains false.
- Iteration 2: low = 4, high = 7 mid = (4 + 7) DIV 2 = 5 names[5] is \"Lily\" Since \"Lily\" < \"Mason\" is True, low becomes mid + 1 = 6. found remains false.
- Iteration 3: low = 6, high = 7 mid = (6 + 7) DIV 2 = 6 names[6] is \"Mason\" Since names[6] == \"Mason\" is True, found becomes true.
Loop terminates because found is true. The target is located at index 6.
Marking scheme
1 mark: Correct initial values and calculation of mid = 3 in iteration 1. 1 mark: Correct update to low = 4 after comparing with \"Grace\". 1 mark: Correct calculation of mid = 5 in iteration 2 and comparison with \"Lily\". 1 mark: Correct update to low = 6 for the third iteration. 1 mark: Correct calculation of mid = 6, setting found = true, and identifying final index as 6.
Question 16 · structured_algorithm_trace
5 marks
A circular queue is implemented using an array Q of size 4 (indices 0 to 3). The queue pointers and size are initialized as head = 0, tail = 0, size = 0. The operations are defined as follows:
procedure enqueue(val) if size == 4 then print(\"Full\") else Q[tail] = val tail = (tail + 1) MOD 4 size = size + 1 endif endprocedure
function dequeue() if size == 0 then return \"Empty\" else val = Q[head] head = (head + 1) MOD 4 size = size - 1 return val endif endfunction
Trace the execution of the following operation sequence:
The final contents of the array Q are [14, 3, 11, 5].
Marking scheme
1 mark: Correct state of Q, tail, size after enqueue(8) and enqueue(3). 1 mark: Correctly updates head to 1 and size to 1 after dequeue() operation. 1 mark: Correctly places 11 at Q[2] and 5 at Q[3] and wraps tail back to 0. 1 mark: Correctly places 14 at Q[0], updates tail to 1, and size to 4. 1 mark: Correctly lists final array Q as [14, 3, 11, 5] and state variables.
Question 17 · structured_algorithm_trace
5 marks
Consider the following nested loop algorithm:
function compute(n) total = 0 for i = 1 to n temp = 1 for j = 1 to i temp = temp * 2 next j total = total + temp next i return total endfunction
Trace the execution of compute(3). Show the values of i, j, temp, and total at each step of the loops. State the final total returned.
Show answer & marking schemeHide answer & marking scheme
Worked solution
We trace the algorithm with n = 3 step-by-step:
Initial state: total = 0
- i = 1: temp is initialized to 1 j loop runs from 1 to 1: j = 1: temp = 1 * 2 = 2 total = total + temp -> total = 0 + 2 = 2
- i = 2: temp is initialized to 1 j loop runs from 1 to 2: j = 1: temp = 1 * 2 = 2 j = 2: temp = 2 * 2 = 4 total = total + temp -> total = 2 + 4 = 6
- i = 3: temp is initialized to 1 j loop runs from 1 to 3: j = 1: temp = 1 * 2 = 2 j = 2: temp = 2 * 2 = 4 j = 3: temp = 4 * 2 = 8 total = total + temp -> total = 6 + 8 = 14
The function exits the outer loop and returns the final value of total, which is 14.
Marking scheme
1 mark: Correctly traces i = 1 iteration, showing temp = 2 and total = 2. 1 mark: Correctly traces i = 2 inner loop, showing temp = 4. 1 mark: Correctly updates total to 6 after i = 2 iteration. 1 mark: Correctly traces i = 3 inner loop, showing temp = 8. 1 mark: Correctly updates total to 14 after i = 3 iteration and states 14.
Question 18 · structured_algorithm_trace
5 marks
The function encode is designed to shift uppercase alphabetical letters in a string by a given offset:
function encode(word, shift) result = \"\" for i = 0 to len(word) - 1 char = subString(word, i, 1) code = asc(char) if code >= 65 and code <= 90 then newCode = code + shift if newCode > 90 then newCode = newCode - 26 endif result = result + chr(newCode) else result = result + char endif next i return result endfunction
Note: - subString(word, start, length) returns a portion of the string. - asc(char) returns the ASCII value of a character (e.g., 'A' = 65, 'B' = 66, ..., 'Z' = 90). - chr(code) returns the character corresponding to the ASCII value.
Trace the execution of encode(\"WXYZ\", 3). Show the step-by-step changes to char, code, newCode, and result at each iteration. State the final returned string.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Initial state: word = \"WXYZ\", shift = 3, result = \"\"
- Iteration i = 0: char = \"W\" code = asc(\"W\") = 87 code is between 65 and 90. newCode = 87 + 3 = 90 90 is not > 90, so result = \"\" + chr(90) = \"Z\"
- Iteration i = 1: char = \"X\" code = asc(\"X\") = 88 code is between 65 and 90. newCode = 88 + 3 = 91 91 > 90 is True, so newCode = 91 - 26 = 65 result = \"Z\" + chr(65) = \"ZA\"
- Iteration i = 2: char = \"Y\" code = asc(\"Y\") = 89 code is between 65 and 90. newCode = 89 + 3 = 92 92 > 90 is True, so newCode = 92 - 26 = 66 result = \"ZA\" + chr(66) = \"ZAB\"
- Iteration i = 3: char = \"Z\" code = asc(\"Z\") = 90 code is between 65 and 90. newCode = 90 + 3 = 93 93 > 90 is True, so newCode = 93 - 26 = 67 result = \"ZAB\" + chr(67) = \"ZABC\"
Loop finishes as i reaches the end. Final returned string is \"ZABC\".
Marking scheme
1 mark: Correctly traces iteration i = 0, updating result to \"Z\". 1 mark: Correctly traces iteration i = 1, wrapping newCode to 65 and updating result to \"ZA\". 1 mark: Correctly traces iteration i = 2, wrapping newCode to 66 and updating result to \"ZAB\". 1 mark: Correctly traces iteration i = 3, wrapping newCode to 67 and updating result to \"ZABC\". 1 mark: Correctly states the final returned value of \"ZABC\".
Question 19 · essay_evaluation
9 marks
A developer is designing a pathfinding system for an NPC in a 2D grid-based adventure game. The grid contains obstacles, and the NPC needs to find a path from a starting position to a target item. Discuss the use of Depth-First Search (DFS) and Breadth-First Search (BFS) for this pathfinding task. Your evaluation should include: the underlying data structures used to implement each search algorithm, the memory efficiency of both algorithms, the ability of each algorithm to find the shortest path, and a recommendation of which algorithm is more suitable for this game, with justification.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Depth-First Search (DFS) vs. Breadth-First Search (BFS) for Grid Pathfinding. 1. Underlying Data Structures: Breadth-First Search (BFS) uses a Queue, which is a First-In, First-Out (FIFO) data structure. When exploring, adjacent unvisited nodes are added to the back of the queue and processed from the front. This forces a level-by-level exploration outward from the starting point. Depth-First Search (DFS) uses a Stack, which is a Last-In, First-Out (LIFO) data structure. This can be implemented explicitly using a stack structure or implicitly using recursion (via the call stack). This causes the algorithm to explore as deep as possible along a single branch before backtracking. 2. Memory Efficiency: BFS is generally less memory-efficient. It must keep all nodes at the current depth level (the 'frontier') in memory. In a large grid, the size of the queue grows exponentially with the depth of the search. DFS is more memory-efficient. It only needs to store the path from the start node to the current node, along with any untried alternatives at each step. Its space complexity is linear with respect to the maximum depth of the search tree. 3. Shortest Path: BFS is guaranteed to find the shortest path (the path with the fewest edges/grid steps) between the starting position and the target in an unweighted grid. This is because it explores all paths of length 1, then all paths of length 2, and so on. DFS does not guarantee the shortest path. It will return the first path it finds that reaches the target, which often results in a highly winding, inefficient, and unnatural path. 4. Recommendation and Justification: BFS is the superior choice for this 2D grid adventure game. If an NPC uses DFS, they may take an incredibly long, winding route to reach a nearby target, which would appear highly unrealistic and unintelligent to the player. The guarantee of the shortest path provided by BFS justifies its higher memory usage, especially since typical game grids are of a size that modern hardware can easily handle.
Marking scheme
Marking Band Guidance (Total: 9 Marks). Level 3 (7-9 Marks): Detailed and accurate explanation of the data structures (Queue/FIFO for BFS; Stack/LIFO for DFS). Thorough comparison of memory usage and why BFS requires more memory than DFS in wide grids. Clear explanation of why BFS guarantees the shortest path whereas DFS does not. Logical and well-supported recommendation of BFS for the NPC pathfinding. Consistent and accurate use of technical vocabulary. Level 2 (4-6 Marks): Identifies the data structures correctly but may lack detail on how they affect the search progression. Compares memory usage or pathfinding optimality, but one area may lack depth or contains minor inaccuracies. Makes a recommendation, but the justification is weak or incomplete. Technical vocabulary is generally used correctly. Level 1 (1-3 Marks): Limited understanding of the algorithms, confusing the data structures or mechanisms. Superficial comparison with major gaps in memory or path optimality. Recommendation is missing, incorrect, or lacks any technical justification. Indicative Content: Data structures: BFS = Queue (FIFO), DFS = Stack (LIFO / Recursion). Memory: BFS stores the whole frontier (high memory footprint), DFS stores only the current path (lower memory footprint). Shortest path: BFS finds shortest path because it explores uniformly outward; DFS traverses deep first and stops at the first path found, which is rarely optimal. Justification: BFS is better for NPC pathfinding because unnatural paths from DFS ruin gameplay realism.
Question 20 · essay_evaluation
9 marks
A software engineering team is developing a file management application. They need to implement two key features: 1. A utility that calculates the factorial of a given integer. 2. A utility that searches through a nested folder structure (directory tree) to find a specific file. A developer suggests using recursion for both utilities. Evaluate this suggestion. In your answer, you should discuss: the differences in memory management (specifically the call stack) between recursive and iterative solutions; the relative execution speed and risk of errors (such as stack overflow) for both approaches; and a recommendation, with justification, of whether recursion or iteration is more appropriate for each of the two utilities.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Recursion vs. Iteration Evaluation. 1. Memory Management and The Call Stack: Recursion relies on the system call stack. Each recursive call allocates a new stack frame in memory. This frame contains the return address, local variables, and parameters of the current call. These stack frames remain in memory until the base case is reached and the calls begin to resolve. This results in space complexity proportional to the depth of recursion. Iteration does not allocate new stack frames. It reuses the same local variables within a single stack frame, updating them through loop constructs. It operates in constant auxiliary space, O(1). 2. Execution Speed and Error Risks: Execution Speed: Recursion has significant runtime overhead because of the time required to allocate, push, and pop stack frames. Iteration is generally much faster as it avoids this system call overhead. Stack Overflow: Because the call stack has a finite size, a recursive function that calls itself too many times will exhaust the stack space, causing a fatal stack overflow crash. Iteration does not carry this risk because it does not grow the call stack. 3. Suitability for the Utilities: Utility 1 (Factorial Calculation) Recommendation: Iteration. Justification: The logic for a factorial is strictly linear and can be written very simply using a loop. Using recursion for factorial is inefficient because it creates N stack frames, risking stack overflow for large numbers without providing any benefit in code readability. Utility 2 (Directory Tree Search) Recommendation: Recursion. Justification: A directory tree is a non-linear, hierarchical tree structure where each folder can contain subfolders. Recursion matches this structure perfectly. Writing this iteratively requires manually implementing and managing a stack or queue data structure, making the code much more complex, harder to read, and prone to bugs.
Marking scheme
Marking Band Guidance (Total: 9 Marks). Level 3 (7-9 Marks): Thorough and accurate explanation of call stack frames, parameters, and return addresses in recursive execution vs. the constant space of iterative loops. Detailed discussion of execution overhead and the mechanism of stack overflow errors. Clear, well-justified recommendations for both utilities: recommending iteration for factorial and recursion for the directory tree traversal, explaining why the structural nature of the data dictates the choice. Fluent use of technical terms. Level 2 (4-6 Marks): Describes stack frames and stack overflow, but may lack technical precision regarding what is stored in a stack frame. Compares recursion and iteration reasonably, but might focus heavily on one aspect (e.g., memory) while neglecting execution speed. Makes correct recommendations for both utilities, but the justifications are somewhat superficial. Level 1 (1-3 Marks): Basic knowledge of recursion (a function calling itself) and iteration (loops). Minimal mention of the call stack or stack overflow. Recommendations may be missing, incorrect, or lack technical reasoning. Indicative Content: Call stack: Recursive calls push frames (local variables, return address) onto the stack. Iteration keeps a single frame and updates variables. Overhead and Stack Overflow: Recursion is slower due to stack push/pop overhead. Risk of stack overflow if recursion depth is too high. Factorial choice: Iteration is better because it is a simple linear process; recursion adds unnecessary overhead and risk. Directory search choice: Recursion is better because tree-like structures are naturally recursive; iterative tree traversal is overly complex.
Question 21 · essay_evaluation
9 marks
An online concert ticketing platform is upgrading its backend architecture to handle high volumes of simultaneous ticket purchases. The technical lead proposes moving from a sequential processing model to a concurrent processing model. Evaluate this proposal. In your answer, you should: explain the difference between sequential and concurrent processing in the context of this ticketing system; discuss the advantages of using concurrent processing for the users; and analyze the potential problems of concurrent processing in this scenario (such as race conditions and deadlocks) and how they can be prevented or managed.
Show answer & marking schemeHide answer & marking scheme
Worked solution
Sequential vs. Concurrent Processing in a Ticketing System. 1. Sequential vs. Concurrent Processing: Sequential processing handles ticket bookings strictly one after the other. If 1,000 users click 'Buy' at the exact same moment, the system places these requests in a queue and processes request 1, then request 2, and so on. No progress is made on a request until the previous one is fully completed. Concurrent processing allows multiple transaction tasks to overlap in time. Multiple processor cores can execute booking requests in parallel, or a single core can slice time between threads. This means many users can search, select, and process payments at the same time. 2. Advantages for Users: Improved Responsiveness: Users do not experience massive delays or timeouts. During peak sales, booking requests are processed immediately rather than waiting at the back of a long queue. Fairer Access: Users can see real-time updates of seat availability, reducing instances where a user waits minutes in a sequential queue only to find the ticket sold out when their request is finally processed. 3. Potential Problems and Mitigation Strategies: Race Conditions (Double Booking): This occurs when two parallel threads read the same data (e.g., Seat 14B is 'Available'), and both attempt to write to it (e.g., Seat 14B is 'Booked by User A' / 'Booked by User B'). If not managed, the database may assign the same seat to two different people. Prevention: Record Locking (Mutexes). When Thread A reads a seat's status to reserve it, it acquires an exclusive lock on that record. Thread B must wait until Thread A either completes the transaction or times out and releases the lock. Deadlocks: This occurs when Thread A locks Seat 1 and is waiting to lock Seat 2, while Thread B locks Seat 2 and is waiting to lock Seat 1. Both threads are blocked indefinitely, waiting for resources held by the other. Prevention: Resource Ordering (e.g., threads must always lock seats in ascending order of seat numbers), or implementing Timeouts (where a lock is automatically released if the transaction does not complete within a few seconds).
Marking scheme
Marking Band Guidance (Total: 9 Marks). Level 3 (7-9 Marks): Clear and precise distinction between sequential and concurrent execution, applied directly to the ticketing context. Detailed analysis of the benefits of concurrency, such as system responsiveness, throughput, and improved UX under heavy load. In-depth explanation of both race conditions (specifically double booking) and deadlocks (mutual waiting). Provides robust, technical solutions to these issues, such as database record locking (mutexes), atomic transactions, or resource ordering/timeouts to prevent deadlocks. Fluent use of technical computer science terminology. Level 2 (4-6 Marks): Describes sequential vs concurrent processing correctly, but may lack deep context application. Identifies benefits to the user, but with less emphasis on technical parameters (like throughput or latency). Mentions race conditions and/or deadlocks, but explaining the mechanics or solutions (like locks) may contain minor gaps or lack detail. Level 1 (1-3 Marks): Shows limited understanding of concurrent processing, possibly confusing it with simple speed increases. Describes problems or solutions superficially (e.g., saying 'use a lock' without explaining how it works or what a race condition is). Minimal use of accurate technical vocabulary. Indicative Content: Concepts: Sequential = one by one; Concurrent = overlapping execution. Benefits: Reduced waiting times, high volume capacity, better server utilization, less lag for buyers. Race Conditions: Multi-threading accessing shared seat data simultaneously leading to double booking. Solved via record-locking / mutual exclusion. Deadlocks: Circular wait state where threads lock resources needed by each other. Solved via timeouts or forced locking sequences.
Question 22 · applied_oop_design
6 marks
A smart home automation company is designing an Object-Oriented Programming (OOP) solution for their heating control system.
They have a base class `SmartDevice` which has the following private attributes: - `deviceID` (string) - `batteryLevel` (integer representing percentage)
The `SmartDevice` class has a constructor that initializes these attributes, and a public method `getDetails()` which returns a string containing the device ID and the battery percentage.
A subclass `SmartThermostat` inherits from `SmartDevice`. It has: - A private attribute `targetTemperature` (float) - A constructor that takes `deviceID`, `batteryLevel`, and `targetTemperature` as parameters. - A public method `setTargetTemp(newTemp)` which updates the target temperature, but only if `newTemp` is between 10.0 and 30.0 (inclusive). If it is outside this range, the target temperature remains unchanged. - An overridden method `getDetails()` that returns the string details from the parent class, concatenated with the target temperature.
Write the class definition for `SmartThermostat` using OCR pseudocode or a standard programming language of your choice.
Show answer & marking schemeHide answer & marking scheme
Worked solution
An exemplary OCR pseudocode class definition for the subclass `SmartThermostat` is shown below:
``` class SmartThermostat inherits SmartDevice private targetTemperature
public procedure setTargetTemp(newTemp) if newTemp >= 10.0 and newTemp <= 30.0 then targetTemperature = newTemp endif endprocedure
public function getDetails() return super.getDetails() + " Target: " + targetTemperature endfunction endclass ```
Marking scheme
1 mark: Correct class header showing inheritance from `SmartDevice` (e.g., `class SmartThermostat inherits SmartDevice` or extends equivalent). 1 mark: Declaring `targetTemperature` as a private attribute. 1 mark: Constructor taking three parameters and calling `super.new(deviceID, batteryLevel)` or equivalent to pass values to the parent constructor. 1 mark: Constructor correctly assigning the `temp` parameter to the `targetTemperature` attribute. 1 mark: Public method `setTargetTemp` correctly checking range constraints (between 10.0 and 30.0 inclusive) and only updating `targetTemperature` if satisfied. 1 mark: Overriding method `getDetails` which calls `super.getDetails()` and concatenates/appends the value of `targetTemperature` before returning.
Question 23 · applied_oop_design
6 marks
A digital library system contains a class `Book` and a class `Library`.
The `Book` class has the following public methods: - `getTitle()` (returns string) - `isBorrowed()` (returns boolean) - `borrowBook()` (updates status to borrowed)
The `Library` class has the following private attributes: - `books` (an array of 100 `Book` objects) - `numBooks` (an integer representing the actual number of books currently stored in the array)
The `Library` class requires: - A constructor that sets `numBooks` to 0. - A public method `findBook(searchTitle)` which searches the `books` array from index 0 up to (but not including) `numBooks`. If a book matching `searchTitle` is found and is not already borrowed, it must call its `borrowBook()` method and return `true`. If the book is not found or is already borrowed, the method returns `false`.
Write the class definition for `Library` using OCR pseudocode or a standard programming language of your choice. You do not need to implement the `Book` class.
Show answer & marking schemeHide answer & marking scheme
Worked solution
An exemplary OCR pseudocode class definition for the `Library` class is shown below:
``` class Library private books[100] private numBooks
public procedure new() numBooks = 0 endprocedure
public function findBook(searchTitle) for i = 0 to numBooks - 1 if books[i].getTitle() == searchTitle then if books[i].isBorrowed() == false then books[i].borrowBook() return true endif endif next i return false endfunction endclass ```
Marking scheme
1 mark: Declaring class `Library` and private attributes `books` (array) and `numBooks`. 1 mark: Constructor `new()` initializing `numBooks` to 0. 1 mark: Method declaration `findBook(searchTitle)` with correct parameter. 1 mark: Loop that iterates through the occupied elements of the `books` array from index 0 to `numBooks - 1`. 1 mark: Correct conditional checks comparing `books[i].getTitle()` with `searchTitle` and testing if `books[i].isBorrowed()` is false. 1 mark: Correctly calling `books[i].borrowBook()`, returning `true` on successful borrow, and returning `false` after the loop if no match is found.
Question 24 · applied_oop_design
6 marks
A video game developer is designing a character class hierarchy.
The base class `Character` is defined with: - A private attribute `name` (string) - A private attribute `health` (integer) - A constructor `new(name)` that sets `name` to the parameter value and `health` to 100. - A public method `reduceHealth(amount)` which decreases the `health` attribute by `amount`.
A subclass `Warrior` inherits from `Character` and has: - A private attribute `shieldStrength` (integer) - A constructor that takes `name` and `shieldStrength` as parameters. It calls the base class constructor to initialize the name, and sets the `shieldStrength` attribute. - A public method `takeDamage(damageAmount)` which does the following: - If `shieldStrength` is greater than or equal to `damageAmount`, the damage is fully absorbed: `shieldStrength` is reduced by `damageAmount`. - If `shieldStrength` is less than `damageAmount`, the shield is broken: the remaining damage (i.e. `damageAmount - shieldStrength`) is subtracted from the character's health using `reduceHealth()`, and then `shieldStrength` is set to 0.
Write the class definition for `Warrior` using OCR pseudocode or a standard programming language of your choice.
Show answer & marking schemeHide answer & marking scheme
Worked solution
An exemplary OCR pseudocode class definition for the subclass `Warrior` is shown below:
``` class Warrior inherits Character private shieldStrength
public procedure new(pName, pShield) super.new(pName) shieldStrength = pShield endprocedure
public procedure takeDamage(damageAmount) if shieldStrength >= damageAmount then shieldStrength = shieldStrength - damageAmount else dim remainingDamage = damageAmount - shieldStrength super.reduceHealth(remainingDamage) shieldStrength = 0 endif endprocedure endclass ```
Marking scheme
1 mark: Correct class header indicating inheritance from `Character` (e.g. `class Warrior inherits Character`). 1 mark: Declaring `shieldStrength` as private attribute. 1 mark: Constructor `new` accepting parameters and calling parent constructor `super.new(pName)`. 1 mark: Constructor initializing `shieldStrength` to `pShield`. 1 mark: `takeDamage` method with correct selection statement comparing `shieldStrength` and `damageAmount`, updating `shieldStrength` when it absorbs all damage. 1 mark: Correctly calculating remaining damage, calling `super.reduceHealth(remainingDamage)` or `reduceHealth(remainingDamage)` and setting `shieldStrength = 0`.
Question 25 · applied_oop_design
6 marks
A fleet tracking system is modeled using Object-Oriented Programming.
The system has an abstract base class `Vehicle` which has: - A private attribute `registration` (string) - A private attribute `mileage` (float) - A constructor `new(registration)` which sets `registration` and initializes `mileage` to 0.0. - An abstract method `calculateFuelConsumption(distance)` which returns a float.
A subclass `ElectricCar` inherits from `Vehicle` and contains: - A private attribute `batteryCapacity` (float, representing the capacity in kWh) - A private attribute `efficiency` (float, representing the miles per kWh of the car) - A constructor that accepts `registration`, `batteryCapacity`, and `efficiency` as parameters. This constructor must call the parent class constructor and initialize the subclass attributes. - An overridden method `calculateFuelConsumption(distance)` which calculates and returns the electrical energy consumed over the given distance (calculated as `distance / efficiency`).
Write the class definition for `ElectricCar` using OCR pseudocode or a standard programming language of your choice.
Show answer & marking schemeHide answer & marking scheme
Worked solution
An exemplary OCR pseudocode class definition for the subclass `ElectricCar` is shown below:
``` class ElectricCar inherits Vehicle private batteryCapacity private efficiency
public procedure new(reg, cap, eff) super.new(reg) batteryCapacity = cap efficiency = eff endprocedure
public function calculateFuelConsumption(distance) return distance / efficiency endfunction endclass ```
Marking scheme
1 mark: Correct class header showing inheritance from `Vehicle` (e.g. `class ElectricCar inherits Vehicle`). 1 mark: Private attributes `batteryCapacity` and `efficiency` correctly declared. 1 mark: Constructor taking 3 parameters (`registration`, `batteryCapacity`, `efficiency`). 1 mark: Constructor correctly calling the parent class constructor with parameter (e.g. `super.new(reg)`). 1 mark: Constructor initializing `batteryCapacity` and `efficiency` with parameters. 1 mark: Overriding function `calculateFuelConsumption(distance)` returning the correct expression `distance / efficiency`.
Wondering how well you actually know this?
Thinka is an AI practice app for DSE students — unlimited questions, instant auto-marking, and detailed step-by-step solutions. 100,000+ students use it to confirm they actually know it, not just think they do.