25-Comp-A6 Software Engineering · December 2016
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
National Exams — December 2016 — 98-Comp-A6 Software Engineering. Three-hour, closed-book exam, no calculator permitted. Format: eight questions, candidates answer any five of the eight (all questions equal weight — each of the five counted questions is worth 20%; only the first five questions as they appear in the answer book are marked). All eight questions are solved below for completeness.
Reference texts: Sommerville, Software Engineering (10th ed., Pearson) — software process models, object-oriented and function-oriented design, software testing, component-based software engineering, verification and validation, distributed software engineering, software evolution/maintenance; Pressman, Software Engineering: A Practitioner's Approach (9th ed.) — supplementary process, testing and architecture coverage; Gamma, Helm, Johnson & Vlissides, Design Patterns — object-oriented design/reuse vocabulary.
Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.
A delivered system's specification is a snapshot of what its stakeholders needed and what its operating environment looked like at one point in time, but neither stays fixed once the system is deployed: the business rules it encodes change (new regulations, new tax rates, new organisational policy), the platform it runs on changes (new operating-system releases, new hardware, deprecated APIs), competitors and users' own expectations shift, and previously undiscovered defects surface once the system is exercised by real usage patterns wider than any test suite covered. This is essentially Lehman's "law of continuing change" for E-type (real-world-embedded) systems: because the system operates inside an environment that keeps moving, a system that is never updated does not stay merely static — it drifts further out of alignment with that environment every time the environment changes without a matching update to the software. It therefore must keep changing to remain fit for purpose; if it does not, it becomes progressively less useful, not through any decay in the code itself (software does not wear out), but because the world it was built to serve has moved on without it.
| Type | Definition | Example |
|---|---|---|
| Corrective | Fixing a defect discovered after delivery — the system is not behaving as its own specification requires. | Patching a null-pointer crash in a production order-processing service that only manifests when a customer's shipping address field is left blank. |
| Adaptive | Modifying the system to keep working correctly as its external environment changes, with no change to what the system is meant to do. | Updating a payroll system's tax-withholding tables for a new tax year's bracket structure, or porting an application to a newly released operating-system version whose old APIs were deprecated. |
| Perfective | Adding new functionality or improving performance/usability that users request, beyond what the original specification required. | Adding a new report type a finance team has asked for, or optimizing a slow database query after users report the system feels sluggish under normal load. |
Empirical studies of industrial maintenance effort (Lientz & Swanson's classic survey is still the commonly-cited figure) find perfective maintenance is typically the largest of the three by effort — roughly half of total maintenance effort — with adaptive next and corrective the smallest share, which runs counter to the popular assumption that maintenance is mostly "bug fixing": most maintenance effort is actually spent making an already-working system do more or do it better, not fixing what it does wrong.
Yes — software engineers carry a professional responsibility to produce code that can be readily evolved, and that responsibility does not depend on the employer or client having explicitly asked for it. The argument rests on the same basis as any other professional obligation in engineering: codes of ethics for the profession (the ACM/IEEE Software Engineering Code of Ethics and Professional Practice, and, for a Canadian-licensed engineer, EGBC's Code of Ethics obliging members to hold paramount the safety, health and welfare of the public and to practice with fidelity, competence and integrity) do not make competent practice conditional on the client asking for it. Producing code that is needlessly difficult to evolve is not a neutral choice of style; per part (a), every delivered system will in fact need to be changed, so unmaintainable code directly causes higher defect rates and higher cost on every future corrective and adaptive change — including whatever safety-relevant patch is needed next — which is a foreseeable, not speculative, future harm.
The argument has a real limit worth stating honestly: a professional obligation to write readable, modular, adequately-tested code is not the same as an obligation to build unlimited speculative flexibility for every future scenario the client never asked for and is not paying for — over-engineering for hypothetical future change can itself waste a client's resources and is a scope/cost matter to be negotiated, not an ethical floor. The responsibility that does not depend on being asked is the baseline: code that a competent engineer can read, test, and safely change; investing further in evolvability beyond that baseline (a more elaborate plugin architecture, extensive configurability) is legitimately something the engineer should raise with the client, but agreeing not to build it is a business decision, not an ethics violation, provided the baseline itself is met.