2025 question paper
Software Engineering
26 questions
Q1a. What was the main cause of the "Software Crisis"? (i) Lack of programming languages (ii) Inability to manage complex software projects effectively (iii) Insufficient hardware resources (iv) Overuse of automation20252m
Module 1: Introduction & SDLC
View this question on its own page →What was the main cause of the "Software Crisis"?
(i) Lack of programming languages
(ii) Inability to manage complex software projects effectively
(iii) Insufficient hardware resources
(iv) Overuse of automationWorked SolutionAnswer: (ii) Inability to manage complex software projects effectively
The Software Crisis (late 1960s onwards) refers to the widespread project failures — late deliveries, blown budgets, buggy software, and projects abandoned altogether — caused primarily by the growing complexity of software and the industry's inability to manage large, complex software projects using ad-hoc, unstructured methods.
Why the others are wrong:
- (i) Lack of programming languages — by the 1960s many languages (FORTRAN, COBOL, ALGOL) existed; the problem was not language availability.
- (iii) Insufficient hardware resources — hardware was advancing rapidly; the bottleneck was software management, not machine resources.
- (iv) Overuse of automation — automation was minimal; this was never the crisis trigger.
The crisis motivated the birth of software engineering as a discipline (application of engineering principles to software development), introducing structured processes, requirements analysis, design, testing, and project management.
Q1b. Which software development model emphasizes risk analysis at every phase? (i) Waterfall model (ii) Incremental model (iii) Spiral model (iv) Prototype model20252m
Module 1: Introduction & SDLC
View this question on its own page →Which software development model emphasizes risk analysis at every phase?
(i) Waterfall model
(ii) Incremental model
(iii) Spiral model
(iv) Prototype modelWorked SolutionAnswer: (iii) Spiral model
The Spiral model (Boehm, 1986) is the SDLC model that explicitly emphasizes risk analysis at every phase of development. Each loop (iteration) of the spiral walks through four quadrants:
- Determine objectives (of the current iteration),
- Identify and resolve risks — risk analysis/prototyping of risky areas,
- Development and testing of the product increment,
- Planning of the next iteration (customer evaluation/review).
The radius of the spiral grows with each iteration, and each pass increases the level of the product. Because the model returns to risk analysis in every loop, it is the best fit for large, high-risk, and complex projects.
Why the others are wrong:
- (i) Waterfall — a purely linear, sequential model with no explicit risk-analysis step.
- (ii) Incremental — delivers the product in parts; risk analysis is not its defining feature.
- (iv) Prototype — focuses on building throwaway prototypes to clarify requirements, not on iterative risk analysis.
Q1c. According to Brooks' "No Silver Bullet," what is the biggest challenge in software engineering? (i) Hardware constraints (ii) Lack of skilled developers (iii) Essential complexity of software (iv) Inadequate documentation20252m
Module 1: Introduction & SDLC
View this question on its own page →According to Brooks' "No Silver Bullet," what is the biggest challenge in software engineering?
(i) Hardware constraints
(ii) Lack of skilled developers
(iii) Essential complexity of software
(iv) Inadequate documentationWorked SolutionAnswer: (iii) Essential complexity of software
In his famous 1987 essay "No Silver Bullet — Essence and Accidents of Software Engineering", Frederick Brooks argues that the greatest difficulty in software engineering is the essential complexity of the software itself — the inherently complex conceptual structures (the "essence" of the problem) that cannot be removed by any tool, methodology, or "silver bullet"—unlike accidental complexities (programming language quirks, tooling) which can be reduced.
Why the others are wrong:
- (i) Hardware constraints — hardware has improved dramatically; it is not the fundamental bottleneck.
- (ii) Lack of skilled developers — a real concern but not the essential difficulty Brooks highlights.
- (iv) Inadequate documentation — an accidental/practice problem, not the inherent nature of software.
Brooks concludes that no single breakthrough can achieve an order-of-magnitude improvement in productivity, reliability, or simplicity because the essential complexity — requirements, design, interlocking concepts — is inherent to software.
Q1d. Which of the following best describes Functional Requirements? (i) Constraints on the software design (ii) Features the system must perform (iii) Performance and reliability requirements (iv) Documentation standards20252m
Module 2: Requirements & SRS
View this question on its own page →Which of the following best describes Functional Requirements?
(i) Constraints on the software design
(ii) Features the system must perform
(iii) Performance and reliability requirements
(iv) Documentation standardsWorked SolutionAnswer: (ii) Features the system must perform
Functional requirements describe what the system must do — the specific functions, features, services, or behaviours the software must provide (e.g., "the system shall allow a user to withdraw cash", "the system shall send an e-mail notification"). They define inputs, outputs, and the processing/transformation rules.
By contrast:
- (i) Constraints on the software design — these are design/implementation constraints (often called non-functional or design constraints).
- (iii) Performance and reliability requirements — these are non-functional requirements (quality attributes such as speed, security, availability).
- (iv) Documentation standards — process/standards issues, not functional behaviour.
So functional requirements = features the system must perform — option (ii).
Q1e. The main purpose of an SRS (Software Requirements Specification) document is to: (i) Describe coding standards (ii) Provide a user manual (iii) Serve as a contract between client and developer (iv) Define the software test cases20252m
Module 2: Requirements & SRS
View this question on its own page →The main purpose of an SRS (Software Requirements Specification) document is to:
(i) Describe coding standards
(ii) Provide a user manual
(iii) Serve as a contract between client and developer
(iv) Define the software test casesWorked SolutionAnswer: (iii) Serve as a contract between client and developer
The Software Requirements Specification (SRS) is a formal document that completely describes the intended purpose, behaviour, and constraints of the software. Its main purpose is to act as a contract/agreement between the customer (client) and the developer regarding exactly what the software will do — serving as the unambiguous reference for design, development, testing, acceptance, and payment.
Why the others are wrong:
- (i) Describe coding standards — coding standards are separate process documents; the SRS is about what to build, not how to code it.
- (ii) Provide a user manual — a user manual describes the finished product to end users; the SRS is written before development.
- (iv) Define the software test cases — test cases are derived from the SRS (testers use it as a basis), but defining them is a later testing activity.
An SRS therefore captures the complete requirements — functional and non-functional — and underpins the client–developer contract.
Q1f. Which of the following is *not* a characteristic of good software design? (i) Low coupling (ii) High cohesion (iii) High complexity (iv) Modularity20252m
Module 3: Software Design & Metrics
View this question on its own page →Which of the following is not a characteristic of good software design?
(i) Low coupling
(ii) High cohesion
(iii) High complexity
(iv) ModularityWorked SolutionAnswer: (iii) High complexity
Good software design aims to produce a system that is maintainable, understandable, and extensible. Its hallmarks are:
- (i) Low coupling — modules depend on each other as little as possible (good),
- (ii) High cohesion — related responsibilities stay together in a module (good),
- (iv) Modularity — the system is broken into independent, manageable modules (good).
High complexity is the opposite of good design — it makes software hard to understand, test, and maintain, and increases defect rates. Therefore "high complexity" is the one that is not a characteristic of good software design — option (iii).
Q1g. In a Data Flow Diagram (DFD), which symbol represents an external entity? (i) Circle (ii) Arrow (iii) Open rectangle (iv) Double line20252m
Module 3: Software Design & Metrics
View this question on its own page →In a Data Flow Diagram (DFD), which symbol represents an external entity?
(i) Circle
(ii) Arrow
(iii) Open rectangle
(iv) Double lineWorked SolutionAnswer: (iii) Open rectangle
In a Data Flow Diagram (DFD) (Yourdon/DeMarco notation):
- (iii) Open rectangle (square/box with three closed sides) represents an external entity — a source or sink of data outside the system boundary (person, department, external system).
- (i) Circle (or rounded rectangle in Gane-Sarson) represents a process/transform.
- (ii) Arrow represents a data flow.
- (iv) Double line / two parallel lines represents a data store.
Hence the symbol for an external entity in a DFD is the open rectangle — option (iii).
Q1h. Cyclomatic Complexity is primarily used to measure: (i) Lines of code (ii) Logical paths in a program (iii) Execution speed (iv) Code documentation quality20252m
Module 3: Software Design & Metrics
View this question on its own page →Cyclomatic Complexity is primarily used to measure:
(i) Lines of code
(ii) Logical paths in a program
(iii) Execution speed
(iv) Code documentation qualityWorked SolutionAnswer: (ii) Logical paths in a program
Cyclomatic complexity (McCabe, 1976) is a software metric that measures the number of linearly independent paths through a program's control-flow graph — i.e., the number of logical decision paths (loops, conditionals) that must be tested. It is computed as
where = number of edges, = number of nodes of the control-flow graph (equivalently , where = number of predicate/decision nodes).
Its main uses:
- Determines the minimum number of test cases required to achieve branch/path coverage.
- Indicates the complexity/testability of a module — high complexity means more paths, more testing, and higher defect potential.
Why the others are wrong:
- (i) Lines of code — that is a size measure (LOC), not cyclomatic complexity.
- (iii) Execution speed — a performance concern, unrelated.
- (iv) Code documentation quality — a maintainability/documentation concern, unrelated.
So cyclomatic complexity primarily measures logical paths in a program — option (ii).
Q1i. In Boundary Value Analysis, test cases are designed based on: (i) Average input data (ii) Input conditions at their limits (iii) Randomly selected inputs (iv) Data from previous projects20252m
Module 4: Software Testing
View this question on its own page →In Boundary Value Analysis, test cases are designed based on:
(i) Average input data
(ii) Input conditions at their limits
(iii) Randomly selected inputs
(iv) Data from previous projectsWorked SolutionAnswer: (ii) Input conditions at their limits
Boundary Value Analysis (BVA) is a black-box (functional) testing technique that designs test cases using the boundary values of the input domain — the values at, just above, and just below the edges of each valid/invalid partition. The rationale is that errors tend to concentrate at the boundaries of input ranges (e.g., for a range [1, 100], test 0, 1, 2, 99, 100, 101).
Why the others are wrong:
- (i) Average input data — typical/mid-range values are not the focus of BVA; boundaries are.
- (iii) Randomly selected inputs — random testing is a different approach (e.g., fuzzing).
- (iv) Data from previous projects — historical data is not how BVA selects cases.
BVA therefore designs test cases based on input conditions at their limits — option (ii).
Q1j. Regression testing is performed to: (i) Test a new module (ii) Ensure recent changes didn't affect existing functionality (iii) Improve system performance (iv) Identify hardware errors20252m
Module 5: Software Maintenance
View this question on its own page →Regression testing is performed to:
(i) Test a new module
(ii) Ensure recent changes didn't affect existing functionality
(iii) Improve system performance
(iv) Identify hardware errorsWorked SolutionAnswer: (ii) Ensure recent changes didn't affect existing functionality
Regression testing re-runs previously passed test cases (and adds new ones) after a change — a bug fix, enhancement, or integration — to verify that the modifications have not broken existing, already-working functionality. It guards against "regressions": defects introduced in code that used to work.
Why the others are wrong:
- (i) Test a new module — testing new code alone is unit/development testing; regression testing focuses on existing behaviour after a change.
- (iii) Improve system performance — performance tuning is not the purpose of regression testing.
- (iv) Identify hardware errors — hardware faults are outside the scope of software regression testing.
So regression testing ensures recent changes didn't affect existing functionality — option (ii).
- Install PocketlyBudget App•POCKETLY
Pocketly on Android
Log daily food, travel, and hostel expenses instantly. Set monthly spending limits and see where your money goes without complex spreadsheets.
Q2a. What are the major characteristics of software that distinguish it from hardware?20257m
Module 1: Introduction & SDLC
View this question on its own page →What are the major characteristics of software that distinguish it from hardware?
Worked SolutionCharacteristics of Software vs Hardware
Software is a logical, non-physical product and differs fundamentally from hardware. The classic distinguishing characteristics (per Pressman/Sommerville):
1. Software is developed/engineered, not manufactured
- Hardware: after design, mass-manufactured (identical copies are cheaply produced on a production line, e.g., a chip made millions of times).
- Software: after design, it is created once and copied — every copy costs almost nothing, but the "manufacturing" is the one-time development cost. Quality must be built in during design, not added later on a production line.
2. Software does not "wear out" (but it does degrade)
- Hardware: follows a bathtub curve — high early failure rate (infant mortality), then a low constant failure rate, then rising failures as components wear out (corrosion, fatigue).
- Software: does not wear out physically. Failures come from design/latent defects, which surface when new usage paths are exercised. Over time, repeated changes introduce new errors, so the software appears to degrade (the "deterioration" is really a result of changes/de-facto error introduction), until it is re-engineered or retired.
3. Much of software is custom-built, not assembled from components
- Hardware is largely built from standard off-the-shelf components.
- Software components are more custom and intertwined; true component reuse is harder, so most software is constructed to fit a specific customer.
4. Software is intangible / loses its nature over time
- Software has no physical mass; it appears as programs, data, and documents. Project progress is not visible ("software has no physical presence"), making schedule and progress measurement difficult compared to hardware.
5. Software is complex, changeable, and not governed by physical laws
- Complexity is inherent (Brooks' essential complexity). Software is flexible — it can be changed late in the cycle more easily than hardware — but this flexibility also invites requirements churn ("software can be changed at any time").
- No physical constraints (no friction, no gravity) govern software, so its behaviour is discrete/logical, and all failures trace back to human/design errors.
Summary table
Aspect Hardware Software Production Manufactured in volume Developed once, then copied Failure pattern Wears out (bathtub curve) Doesn't wear out; fails from design defects Change Physically expensive to change Easy to change logically, but risky to manage Tangibility Physical Intangible (logic) Scope of reuse Standard components common Reuse still difficult Quality focus Production process Design and process discipline Q2b. Explain Software Development Life Cycles. Compare the Waterfall Model and Agile model of software development.20257m
Module 1: Introduction & SDLC
View this question on its own page →Explain Software Development Life Cycles. Compare the Waterfall Model and Agile model of software development.
Worked SolutionSoftware Development Life Cycle (SDLC) + Waterfall vs Agile
SDLC — Phases
The Software Development Life Cycle is a structured process for developing software. Its phases:
- Communication / Requirement Gathering — collecting user & system requirements, feasibility study.
- Planning — project planning, estimation, scheduling, risk analysis.
- Modeling / Analysis & Design — analyzing requirements; producing design (architecture, data design, interface design).
- Construction / Coding — implementation of the design in code (unit testing during coding).
- Testing — verification & validation, defect fixing (integration, system, acceptance).
- Deployment / Delivery — installation, release, user training.
- Maintenance — corrective, adaptive, perfective, preventive changes after delivery.
Any SDLC model arranges these phases in a particular order with particular feedback.
Waterfall Model
- Linear-sequential: each phase must be completed before the next begins; no overlap; document-driven.
- Phases: Requirements → Design → Implementation → Testing → Deployment → Maintenance (with strict phase-exit gates).
- Advantages: simple, disciplined, well-documented; works when requirements are fixed and clear; easy to manage milestones.
- Disadvantages: no feedback loops; late discovery of requirement/design errors is costly; not suitable for uncertain/volatile requirements.
Agile Model
- Iterative-incremental: the product is built in short sprints/iterations (1–4 weeks), each delivering a working increment.
- Principles: customer collaboration over contract negotiation, working software over comprehensive documentation, responding to change over following a plan; continuous feedback, self-organizing teams, daily stand-ups, frequent releases (Scrum, XP, Kanban).
- Advantages: adaptable to changing requirements; early and continuous delivery of value; high customer involvement; risks visible early.
- Disadvantages: less emphasis on documentation; requires close/full-time customer availability; hard to scale/estimate precisely for very large distributed projects.
Comparison table
Aspect Waterfall Agile Approach Linear sequential Iterative & incremental Requirements Fixed/known upfront Evolving; change welcomed Customer involvement At milestones Continuous throughout Delivery Single release at end Frequent working increments Documentation Heavy/documented Minimal ("just enough") Feedback Late (after phase) Each iteration Best for Stable, well-understood projects Dynamic, evolving requirements Risk handling High risk if delayed discovery Risks surfaced early per sprint Q3a. Define Requirement Analysis. Why is it considered one of the most critical stages in the software development life cycle?20257m
Module 2: Requirements & SRS
View this question on its own page →Define Requirement Analysis. Why is it considered one of the most critical stages in the software development life cycle?
Worked SolutionRequirement Analysis — Definition & Why It Is Critical
Definition
Requirement Analysis (requirements engineering) is the systematic process of:
- Eliciting (gathering) requirements from stakeholders (users, clients, domain experts),
- Analyzing & negotiating them (resolving conflicts, prioritizing),
- Specifying/documenting them in an SRS (Software Requirements Specification),
- Validating/verifying them (checking correctness, completeness, consistency, feasibility).
It answers the question "What must the software do?" before any design or coding begins.
Why it is the most critical stage of the SDLC
Errors here are the costliest. Studies (e.g., Boehm) show that fixing a requirements error after deployment can cost 50–200× more than fixing it during requirements analysis. A wrong requirement propagated through design and code wastes enormous effort.
It drives everything downstream. The SRS is the input for design, coding, testing, acceptance, and user documentation. If requirements are wrong/incomplete, every later phase inherits the defect ("garbage in, garbage out").
Misunderstanding is the top cause of project failure. The majority of failed/over-budget projects trace back to incomplete requirements and poor communication between stakeholders.
It sets the contract baseline. The SRS becomes the agreement between customer and developer: it defines scope, so change control, pricing, and acceptance testing all reference it.
It reduces rework and risk. Clear analysis detects incompleteness, ambiguity, and non-feasible demands early — reducing rework, schedule slippage, and cost overruns.
Consequences of skipping it
- Building the wrong product (meets the letter of a misheard requirement, not the user need).
- Scope creep, frequent changes, and endless rework.
- Impossible or un-testable expectations discovered late.
Summary: requirement analysis is critical because its errors are the most expensive to fix, it feeds every subsequent phase, it anchors the client–developer contract, and it is where feasibility and scope are defined.
Q3b. Explain the purpose of a Software Requirements Specification (SRS). What standards or attributes should a good SRS doc contain?20257m
Module 2: Requirements & SRS
View this question on its own page →Explain the purpose of a Software Requirements Specification (SRS). What standards or attributes should a good SRS doc contain?
Worked SolutionPurpose of the SRS & Qualities of a Good SRS
Purpose of the Software Requirements Specification (SRS)
The SRS is a formal, documented statement of the complete requirements of the software to be built. Its purposes:
- Contract / agreement baseline — an unambiguous, agreed-upon description of what the system will do, shared by customer and developer (basis for scope, payment, acceptance).
- Communication medium — a common reference that lets users, analysts, designers, testers, and managers understand the system consistently.
- Basis for design and implementation — the designer derives architecture/modules from it; the coder implements to it.
- Basis for testing / V&V — test cases, acceptance tests, and validation criteria are derived from the stated requirements.
- Input to project planning and estimation — supports effort/cost/schedule estimation and risk analysis.
- Change control baseline — later change requests are evaluated against the frozen SRS.
Attributes / qualities of a good SRS
A good SRS should be (quoting IEEE 830 standard characteristics):
- Correct — every requirement stated is one the software shall actually meet (truthfully reflects the real need).
- Unambiguous — every requirement has exactly one interpretation; no vague words like "fast", "user-friendly", "etc.". (Often checked by formal/structured specification.)
- Complete — includes all functional and non-functional requirements, all inputs/outputs, all constraints, and defined behaviour for all inputs.
- Consistent — no requirement conflicts with another (no contradictions between sections).
- Verifiable — each requirement can be checked/tested by a finite process (e.g., "response < 2 s" is verifiable; "fast" is not).
- Traceable — each requirement is uniquely identified and traceable to its origin (stakeholder need) and to design/test artifacts.
- Ranked for importance/stable — requirements are prioritized (e.g., must/should/may) so trade-offs can be made; also modifiable yet controlled by change management.
- Modifiable — structured so that changes can be made consistently without rewriting the document.
Structure (typical)
- Introduction (purpose, scope, definitions, references, overview)
- Overall description (product perspective, functions, user characteristics, constraints, assumptions)
- Specific requirements (functional requirements, non-functional requirements — performance, security, reliability, portability; external interfaces; design constraints)
- Appendices/index
Summary: the SRS is the agreed definition of "what to build"; a good one is correct, unambiguous, complete, consistent, verifiable, and traceable.
Q4a. Compare the top-down and bottom-up approaches in software design, with examples of when each is appropriate.20257m
Module 3: Software Design & Metrics
View this question on its own page →Compare the top-down and bottom-up approaches in software design, with examples of when each is appropriate.
Worked SolutionTop-Down vs Bottom-Up Software Design
Top-Down Design (Stepwise Refinement)
The system is first viewed at a high level of abstraction and then progressively decomposed into smaller, more detailed sub-modules, until each piece is trivial to implement.
System (high level) ├── Subsystem A │ ├── Module A1 │ │ └── ... │ └── Module A2 └── Subsystem B └── ...- Process: start from the "big picture" → break into subsystems → modules → functions. Each level is designed before descending to the next.
- Advantages: clear overall structure, good for large teams and architecture-first projects; easier to verify that the decomposition satisfies the high-level requirements; encourages design review at each level.
- Disadvantages: risk of missing low-level details that affect the design until late; modules designed in isolation may need rework when integration details emerge.
Bottom-Up Design
Design starts with the low-level primitive components/modules first, then combines them into higher-level systems, ultimately building the complete application.
Functions / Primitives (detailed) ├── combine → Module 1 ├── combine → Module 2 └── ... └── combine → System- Process: identify and build reusable building blocks → group into subsystems → assemble the whole system.
- Advantages: components are well-tested in isolation; promotes reuse; integration of pre-built pieces can be quicker; useful when building libraries or when low-level constraints dominate.
- Disadvantages: the overall structure may be unclear until late; risk of building components that do not fit the system's actual needs; integration problems can appear late.
Comparison table
Aspect Top-Down Bottom-Up Starting point High-level system Low-level components Direction Decompose (refine) Compose (assemble) Clarity of architecture Early Late Component reuse Lower Higher Risk High-level errors costly Integration surprises Best when Requirements are clear, system is new, architecture-first Reusing existing components, libraries, prototyping Test approach Stubs needed for lower levels Drivers needed for higher levels When each is appropriate — examples
- Top-down: building a new enterprise ERP where the overall business processes are known and the architecture must be laid out first; classic structured design projects.
- Bottom-up: developing a class library / utility framework where the primitives (e.g., sorting, string handling) are built and tested first, then assembled into a framework; also GUI widget libraries or embedded-systems drivers.
In practice, most projects use a hybrid: top-down for overall architecture and bottom-up for reusable/tried components, integrating both iteratively.
Q4b. What is a design pattern? Provide an example of a design pattern and explain its use.20257m
Module 3: Software Design & Metrics
View this question on its own page →What is a design pattern? Provide an example of a design pattern and explain its use.
Worked SolutionDesign Patterns — Definition & Example
What is a design pattern?
A design pattern is a general, reusable solution to a commonly occurring design problem within a given context in software design. It is a proven template — not finished code, but a description of how to solve a recurring problem, including the classes, responsibilities, and relationships involved.
Parts of a pattern:
- Name — a standard vocabulary term (e.g., Singleton, Observer).
- Problem — the context/situation where the pattern applies.
- Solution — the elements (classes/objects), their responsibilities, and relationships.
- Consequences — trade-offs, benefits, and drawbacks of applying the pattern.
Categories (GoF — Gang of Four): Creational (object creation), Structural (composition of classes/objects), Behavioral (interaction/responsibility between objects).
Example: The Observer pattern (behavioral)
Problem: One object (subject) changes, and many dependent objects need to be notified/updated automatically — without the subject knowing the specifics of the dependents (loose coupling). Example: a stock-ticker application where a price change must refresh several displays/charts.
Solution:
- Subject maintains a list of observers and provides
attach(),detach(),notify(). - Observer interface defines
update(). - Concrete observers register with the subject; when the subject's state changes it calls
notify(), which invokesupdate()on every registered observer.
┌──────────────┐ attach/notify ┌────────────────┐ │ Subject │◀─────────────────│ Observer │ │──────────────│ │ update() │ │ attach(obs) │ └────────────────┘ │ detach(obs) │ ▲ │ notify() │ │ implements └──────┬───────┘ │ │ state change ┌─┴────────────┐ └────── notify all ────────────▶│ ConcreteObs │ └──────────────┘Use/benefit: the displays and the data model are decoupled; adding a new display requires no change to the subject (open–closed principle). Used in event systems, MVC (model notifies views), and pub-sub messaging.
Why patterns are useful
- Capture proven design experience (not invented from scratch).
- Provide a shared design vocabulary among developers.
- Make designs more maintainable, extensible, and easier to communicate/review.
Other examples: Singleton (one instance), Factory Method (object creation delegated), Adapter (interface conversion), Strategy (interchangeable algorithms).
Q5a. What is the purpose of software measurement and metrics? How can they improve software quality or project management?20257m
Module 3: Software Design & Metrics
View this question on its own page →What is the purpose of software measurement and metrics? How can they improve software quality or project management?
Worked SolutionSoftware Measurement and Metrics — Purpose and Benefits
What is software measurement?
Software measurement is the process of quantifying attributes of software — the product (size, complexity, defects), the process (effort, time, productivity), and the project (schedule, resources) — using well-defined measures.
A metric is a measurement standard/indicator, e.g.:
- Size metrics: LOC (lines of code), function points (FP), object points.
- Complexity metrics: cyclomatic complexity (McCabe), Halstead metrics, coupling/cohesion measures.
- Quality metrics: defect density, mean time to failure, customer-reported defects.
- Process/project metrics: effort (person-months), schedule (duration), productivity (LOC/PM), schedule slippage, cost variance.
Purpose of measurement
- Understand and control the software process and product objectively.
- Predict effort, cost, schedule, and defect levels (estimation models use size/complexity metrics).
- Compare — across projects, teams, or modules (benchmarking).
- Identify problem areas early (complex modules → high defect risk).
- Improve — guide process improvement (e.g., CMM/SPICE) with factual data rather than intuition.
How metrics improve software quality
- Defect density (defects/KLOC) highlights modules needing more testing/refactoring.
- Cyclomatic complexity indicates how many test cases/paths are needed and flags overly complex code that is error-prone.
- Test coverage measures (branch/statement coverage) reveal untested areas.
- Mean time to failure / reliability metrics quantify the product's robustness.
How metrics improve project management
- Estimation: size (FP) and past productivity data drive effort/cost/schedule estimates.
- Tracking/control: effort and schedule variance metrics alert managers to deviations early (earned value analysis).
- Productivity trends guide staffing and process changes.
- Risk management: complexity metrics flag risky modules requiring more review/testing.
Requirements for good metrics (Practical Software Measurement principles)
- Metrics must be objective, measurable, consistent, and useful; data must be collected consistently over time; metrics should be tied to goals (GQM — Goal-Question-Metric) so they drive decisions rather than being collected for their own sake.
Summary: measurement turns software development from an art into a manageable engineering discipline — giving objective data to predict, control, and improve both product quality and project management.
Q5b. Describe Cyclomatic Complexity and how it is used to measure software. What insight does it provide?20257m
Module 3: Software Design & Metrics
View this question on its own page →Describe Cyclomatic Complexity and how it is used to measure software. What insight does it provide?
Worked SolutionCyclomatic Complexity (McCabe)
Definition
Cyclomatic complexity is a software metric that measures the number of linearly independent paths through a program's control-flow graph (CFG). It was introduced by Thomas J. McCabe in 1976 as a measure of a module's structural complexity and testability.
Computation
Given the control-flow graph (nodes = statements/decision points, edges = control flow):
where:
- = number of edges,
- = number of nodes.
Equivalent forms:
where = number of predicate/decision nodes (e.g., if, while, case, &&, ||), and
where = number of regions into which the graph partitions the plane.Example — a program with:
if (a) { ... } else { ... } → 1 decision while (b) { ... } → 1 decision(three independent paths: if-true, if-false-through-loop, and loop iterations).
What it measures / insight it provides
- Minimum number of test cases — equals the number of independent paths, so it gives the minimum number of test cases needed to execute every statement & branch (basis-path testing).
- Complexity / maintainability — high ⇒ more decision paths ⇒ harder to understand, test, and maintain; more likely to contain defects.
- Guidelines: modules with are considered simple and maintainable; values > 10 (some say > 15/20) flag modules that should be refactored/split or given extra testing & review.
- Testing focus: it identifies the structural risk areas so testers can concentrate effort where paths and branches are numerous.
Benefits
- Objective, easily automated (computed directly from source/CFG).
- Combines with other metrics (LOC, coupling) for quality prediction.
- Used in safety-critical and aviation standards (e.g., DO-178B) as a threshold for module complexity.
Summary: cyclomatic complexity quantifies the logical path structure of a program — guiding how many tests to write and which modules are dangerously complex — making it one of the most widely used structural metrics.
Q6a. Explain boundary value analysis and equivalence class testing in functional testing? How do they help?20257m
Module 4: Software Testing
View this question on its own page →Explain boundary value analysis and equivalence class testing in functional testing? How do they help?
Worked SolutionBoundary Value Analysis & Equivalence Class Testing (Functional Testing)
Both are black-box (functional) testing techniques that design test cases from the input specifications without looking at internal code.
Equivalence Partitioning (Equivalence Class Testing)
Idea: Partition the input domain into classes such that all values in one class are expected to be treated identically by the program (same output/behaviour). Then test one representative value from each class — this drastically reduces the number of test cases while keeping high coverage.
Rules for partitioning:
- Valid equivalence classes — inputs the system should accept.
- Invalid equivalence classes — inputs the system must reject.
Example: A field accepts integers 1–100.
- Valid class: {1 ≤ x ≤ 100} → test one value, e.g., 50.
- Invalid class 1: {x < 1} → test, e.g., 0 (or −5).
- Invalid class 2: {x > 100} → test, e.g., 200.
- (Non-integers form further invalid classes.)
Benefit: systematic coverage of the whole input domain with minimal test cases; it reveals the presence of "class-wide" defects (a whole category of inputs mishandled).
Boundary Value Analysis (BVA)
Idea: Experience shows errors concentrate at the boundaries of input ranges (off-by-one mistakes are the most common defect). BVA therefore tests the values on and immediately around each boundary: minimum, just-above-minimum, just-below-maximum, maximum (and, depending on the flavour, also nominal interior values).
For the range [1, 100]:
- Test 1, 2 (lower boundary + just above),
- Test 99, 100 (just below max + max),
- Optionally 0 and 101 (just outside, invalid).
Benefit: catches off-by-one and boundary-handling errors that equivalence partitioning alone would miss; extremely cost-effective because most real defects sit at boundaries.
How they help
- High fault-detection per test case — both techniques target where defects actually cluster (representative classes + edges).
- Reduced test count — instead of exhaustive input testing, a few well-chosen values cover the domain.
- Complementary — equivalence partitioning provides representative coverage inside the classes; BVA adds coverage at the edges, so used together they give strong functional coverage.
Example summary (input 1–100)
Technique Test values Equivalence classes 50 (valid), 0 & 101 (invalid) BVA 1, 2, 99, 100 (and 0, 101 as boundaries) Q6b. Describe unit testing, integration testing and system testing—how they differ and what each addresses.20257m
Module 4: Software Testing
View this question on its own page →Describe unit testing, integration testing and system testing—how they differ and what each addresses.
Worked SolutionUnit, Integration & System Testing
These are the three classic levels of software testing, performed in sequence as components are progressively assembled.
1. Unit Testing
- What: tests the smallest testable unit — an individual function, method, class, or module — in isolation.
- What it addresses: verifies that the unit's internal logic is correct — branches, boundary values, error handling, expected outputs for given inputs.
- Who/how: done by developers during coding, using test drivers/stubs and frameworks (JUnit, pytest, NUnit). Typically white-box (statement/branch coverage).
- Goal: catch local logic errors as early as possible.
2. Integration Testing
- What: tests the interaction between integrated units/modules — the interfaces, data flow, and control flow across module boundaries.
- What it addresses: interface mismatches — wrong parameter passing, incompatible data formats, missing/duplicate functions, ordering/timing problems.
- Strategies:
- Top-down — test high-level modules first, using stubs for lower ones.
- Bottom-up — test low-level modules first, using drivers for higher ones.
- Sandwich / mixed; and Big-bang — all modules integrated at once then tested.
- Goal: find interface/assembly errors that unit tests cannot.
3. System Testing
- What: tests the complete, fully integrated system as a whole against the requirements/SRS.
- What it addresses: end-to-end behaviour, functional requirements, and non-functional attributes — performance, security, usability, reliability, recovery, stress/load, compatibility.
- Who/how: by an independent test team in an environment close to production; primarily black-box.
- Goal: validate that the whole system satisfies its specification.
Comparison table
Aspect Unit Testing Integration Testing System Testing Scope Single unit/module Groups of interacting modules Whole system Focus Internal logic Interfaces & interaction Requirements compliance Test basis Code design Module interfaces SRS/requirements Nature White-box White/black-box Black-box Performed by Developers Developers/testers Independent test team Typical tools JUnit, pytest Test harnesses, drivers/stubs Automation/performance tools Example calculateTax()returns right valueModule A correctly calls B's API End-to-end login → order → invoice flow Order: Unit → Integration → System (each building on the previous). After system testing come acceptance testing (user validates the system against business needs).
- Install PocketlyBudget App•POCKETLY
Pocketly on Android
Log daily food, travel, and hostel expenses instantly. Set monthly spending limits and see where your money goes without complex spreadsheets.
Q7a. Explain the concepts of alpha testing and beta testing. What are their roles in the release cycle of software?20257m
Module 4: Software Testing
View this question on its own page →Explain the concepts of alpha testing and beta testing. What are their roles in the release cycle of software?
Worked SolutionAlpha Testing and Beta Testing
Both are acceptance-stage test levels performed near the end of development, with real users, to validate the software before release.
Alpha Testing
- What: the software is tested on the developer's site, by the internal development/QA team (and sometimes a limited set of customers) in a controlled environment.
- When: after system testing, just before beta.
- Characteristics:
- Controlled environment; developers are available to fix defects on the spot.
- Uses realistic data and user scenarios.
- Finds many defects before external exposure.
- Usually performed in two phases: alpha (in-house testing) — may be white-box/black-box combined.
- Role in release cycle: first real-run validation; ensures the product is stable enough to hand to outside users.
Beta Testing
- What: the software is distributed to a selected set of real, external end users (or a public beta group) who use it in real working environments.
- When: after alpha; the final stage before general release.
- Characteristics:
- Performed at user sites, not the developer's — uncontrolled, real-world conditions.
- Users report defects, usability issues, and missing features; feedback is collected.
- Software is essentially feature-complete; focus is on validation in the real environment.
- Role in release cycle: validates the product under genuine usage, builds market confidence, catches environment-specific problems (OS versions, hardware, integration), and provides a marketing/preview channel. Two variants: open beta (public) and closed beta (invited users).
Comparison table
Aspect Alpha Testing Beta Testing Location Developer's site End-user's site Participants Internal team + invited users Real external users Environment Controlled Uncontrolled/real Defect fixing Immediate Collected for next release Stage Before beta Before general release Focus Technical stability Real-world validation & feedback Summary: alpha testing confirms the product is ready to leave the developer; beta testing confirms it works for real users in the real world — together they de-risk the final release.
Q7b. What is configuration management in the context of software maintenance? Why is it important?20257m
Module 5: Software Maintenance
View this question on its own page →What is configuration management in the context of software maintenance? Why is it important?
Worked SolutionConfiguration Management in Software Maintenance
What is Configuration Management (SCM)?
Software Configuration Management is the discipline of identifying, organizing, and controlling changes to the software throughout its life cycle — especially during maintenance, when the software is constantly being modified. It ensures that changes are made systematically and that the system remains consistent and traceable at every point.
Core activities (the 5 pillars of SCM)
- Configuration Identification — defining and labelling the configuration items (CI): source files, documents, data, build scripts, executables — each assigned a unique identifier/version.
- Version Control — tracking every version/revision of each configuration item, enabling retrieval of any historical state (e.g., Git, SVN).
- Change Control — a formal process for requesting, evaluating (CCB — Change Control Board), approving, implementing, and reviewing changes:
Change request → impact analysis → CCB approval → implement → verify → update baselines - Configuration Status Accounting — recording and reporting the status of all CIs and change requests (what changed, when, by whom, why).
- Configuration Audit / Review — verifying (functional & physical audits) that the delivered configuration matches the approved specifications and that records are accurate.
Baselines
A baseline is a formally reviewed and agreed-upon snapshot of configuration items (e.g., the SRS baseline, design baseline, code baseline). After a baseline is set, changes are made only through formal change control; baselines provide stable reference points for development, testing, and delivery.
Why is it important (especially in maintenance)?
- Control of change chaos — maintenance is a long stream of fixes and enhancements; without SCM, uncontrolled changes corrupt the system ("code drift").
- Traceability & reproducibility — you can always reconstruct exactly which versions produced a given build/release; critical for debugging field failures and for legal/audit compliance.
- Team coordination — prevents conflicting edits; multiple maintainers can work in parallel safely.
- Risk reduction — rollback to a known-good state is always possible if a change fails.
- Support for multiple versions/sites — maintenance often involves supporting several releases (customer-specific versions); SCM manages all of them.
- Quality assurance — audits and baselines give management confidence that delivered software matches what was approved and tested.
Summary: Configuration management is the backbone of software maintenance — it keeps every change identified, controlled, recorded, and auditable so the evolving software never loses its consistency, traceability, or recoverability.
Q8a. Describe different models of software maintenance (corrective, adaptive, perfective, preventive) and give examples.20257m
Module 5: Software Maintenance
View this question on its own page →Describe different models of software maintenance (corrective, adaptive, perfective, preventive) and give examples.
Worked SolutionModels of Software Maintenance (Corrective, Adaptive, Perfective, Preventive)
After delivery, software undergoes changes. Software maintenance is traditionally classified into four types (per IEEE and Pressman/Sommerville):
1. Corrective Maintenance
- What: fixing errors/defects (bugs) discovered in the software after it has been delivered.
- Purpose: restore the software to its intended, correct behaviour.
- Examples: fixing a crash when a specific input is entered; correcting a wrong calculation; patching a security vulnerability.
2. Adaptive Maintenance
- What: modifying the software to respond to changes in its environment — new operating systems, new hardware, new compilers, changed regulations, or new external interfaces.
- Purpose: keep the software working in a changed external environment.
- Examples: porting the application to run on a new Windows/Linux version; updating to support a new database server or browser; changing tax calculations for new government rules.
3. Perfective Maintenance
- What: improving/enhancing the software — adding new features, improving performance, usability, or maintainability — to meet new or changed user needs.
- Purpose: make the software better from the user's perspective (not fixing bugs).
- Examples: adding a new reporting feature; optimizing the response time of a query; redesigning a user interface for better usability.
4. Preventive Maintenance
- What: preventing future problems by making changes that improve the software's maintainability and reliability without changing its external functionality in the short term.
- Purpose: reduce the risk of future failures and lower future maintenance cost (like servicing a machine before it breaks).
- Examples: refactoring complex code; updating comments/documentation; adding comments, restructuring modules, applying better error handling — often using reverse/forward engineering for re-engineering.
Summary table
Type Trigger Activity Example Corrective Bugs/defects Fix errors Crash fix, wrong output fix Adaptive Environment change Adjust to new environment Port to new OS, new DB Perfective User needs Enhance/improve Add features, boost performance Preventive Future risk Re-engineer/harden Refactor, improve docs, code restructuring Note: reports on maintenance distribution (Lientz & Swanson) show perfective (~50%) and adaptive (~25%) dominate, while corrective is often overestimated; preventive is the smallest but pays off over the long term.
Q8b. Define coupling and cohesion in module design. Why is low coupling and high cohesion preferred?20257m
Module 3: Software Design & Metrics
View this question on its own page →Define coupling and cohesion in module design. Why is low coupling and high cohesion preferred?
Worked SolutionCoupling and Cohesion in Module Design
Both are design-quality measures for the modules that make up a system.
Cohesion
Cohesion measures the degree to which the elements inside a single module belong together — how strongly the module's internal parts are related to a single purpose.
- High cohesion (good): the module performs one well-defined logical task; all its elements contribute to that task. Easy to understand, test, and reuse.
- Low cohesion (bad): a module does many unrelated things (e.g., a "utility" module mixing file I/O, math, and GUI code); hard to understand, test, and maintain.
Cohesion levels (best → worst):
- Functional cohesion — all elements contribute to one function (best).
- Sequential cohesion — output of one part feeds the next.
- Communicational cohesion — parts operate on the same data.
- Procedural cohesion — parts follow a process/sequence.
- Temporal cohesion — parts executed at the same time.
- Logical cohesion — parts are logically similar but unrelated (e.g., all error messages).
- Coincidental cohesion — parts have no meaningful relationship (worst).
Coupling
Coupling measures the degree of interdependence between different modules — how much one module depends on another.
- Low coupling (good): modules are independent; changes in one module have little impact on others.
- High coupling (bad): modules are tightly interwoven; a change in one ripples through many, making maintenance and testing hard.
Coupling levels (best → worst):
- Data coupling — modules share data via parameters (best).
- Stamp coupling — share a data structure (record) but only use part of it.
- Control coupling — one module passes control information (flags) to another.
- External coupling — share an externally imposed format/protocol.
- Common coupling — share global data.
- Content coupling — one module directly accesses/alters the internals of another (worst).
Why low coupling + high cohesion is preferred
- Maintainability — a change stays local: with high cohesion, the change belongs to one module; with low coupling, other modules are unaffected. This directly reduces maintenance cost and effort.
- Understandability — each module is a self-contained, single-purpose unit, easy to read.
- Reusability — cohesive, loosely coupled modules can be lifted out and reused in other systems.
- Testability — modules can be unit-tested in isolation; fewer inter-module interactions to cover.
- Reliability & reduced defect spread — errors are contained within a module instead of propagating.
- Parallel development — teams can develop modules concurrently with minimal coordination conflicts.
Idea Good Bad Cohesion High (functional) Low (coincidental) Coupling Low (data) High (content) Summary: "high cohesion, low coupling" is a cornerstone design objective — it yields modules that are simple to build, test, maintain, and reuse.
Q9a. What is software maintenance? Why is it an inevitable phase in the software life-cycle?20257m
Module 5: Software Maintenance
View this question on its own page →What is software maintenance? Why is it an inevitable phase in the software life-cycle?
Worked SolutionSoftware Maintenance — Definition & Why It Is Inevitable
Definition
Software maintenance is the process of modifying a delivered software system to correct defects, adapt it to a changed environment, improve its performance or add features, and prevent future faults — after the software has been released for use. It is the final (and longest) phase of the SDLC.
Maintenance is classified into four types:
- Corrective — fixing bugs/errors.
- Adaptive — adjusting to changes in the environment (OS, hardware, regulations).
- Perfective — enhancing/improving the product (new features, better performance).
- Preventive — refactoring/hardening to avoid future problems.
Why maintenance is inevitable
Errors are never fully eliminated. Testing can never prove the absence of defects; latent bugs always surface during real use, requiring corrective maintenance.
The environment always changes. New operating systems, browsers, hardware, compilers, databases, and legal/regulatory requirements appear continuously — the software must be adapted (adaptive maintenance).
User requirements keep evolving. As users gain experience with the system, they discover new needs and improvements; organizations also change their business processes, driving perfective changes.
Software is "soft" — change is expected. Unlike hardware, software is expected to be changeable; users and managers naturally request modifications after delivery.
Systems live a long life. Software often outlives its original architecture and developers. The working system becomes a valuable asset that must be kept alive through maintenance rather than rewritten (rewriting risks losing behaviour, and is expensive).
Maintenance is huge. Maintenance typically consumes 60–80% of total life-cycle cost and the majority of the effort of software organizations — proof that it cannot be avoided; it is the dominant phase of the life cycle.
Prevention requires maintenance too. Even "do-nothing" software eventually needs preventive/re-engineering to remain maintainable.
The maintenance paradox / last phase reality
Since both the software and its environment keep changing while the software is in use, some form of modification is unavoidable — making maintenance intrinsically inevitable, not optional. The only practical choice is to plan for it (good documentation, modular design, configuration management) so it is manageable.
Summary: maintenance is unavoidable because (a) defects always remain, (b) the environment always changes, and (c) requirements always evolve — and because delivered software is a long-lived asset that must be kept both working and cost-effective.
Q9b. Explain reverse engineering and software re-engineering. How do they relate to legacy systems?20257m
Module 5: Software Maintenance
View this question on its own page →Explain reverse engineering and software re-engineering. How do they relate to legacy systems?
Worked SolutionReverse Engineering and Software Re-engineering
Reverse Engineering
Reverse engineering is the process of analyzing an existing software system (or hardware) to identify its components and their interrelationships and to create representations of the system at a higher level of abstraction — deriving design information from the code. The system itself is not changed; it is a recovery/'understanding' activity.
- Typical outputs: design models recovered from code — e.g., structure charts, UML class/sequence diagrams, dataflow diagrams, pseudo-code or architecture-level descriptions.
- Activities: extracting program structures, identifying modules, building call graphs, regenerating documentation.
- Purpose:
- Understanding legacy systems whose documentation is lost/outdated,
- Re-documentation (create/update documentation),
- Design recovery (reconstruct design decisions),
- Preparing for future changes, migration, or re-implementation;
- also used in security (e.g., malware analysis) and interoperability research.
Legacy code ──[reverse engineering]──▶ High-level design / documentation (no code change)Re-engineering (Software Re-engineering)
Re-engineering is the examination and alteration of a subject system to reconstitute it in a new form with the goal of improving quality, maintainability, and evolvability — it is a forward-engineering-like reconstruction of the existing system. It changes the system.
- Typical re-engineering process (the "re-engineering model"):
- Inventory analysis — catalogue existing system/quality.
- Reverse engineering — understand the existing system (recover design).
- Restructuring — reorganize code/data without changing functionality (improve structure, remove dead code, convert to structured forms).
- Forward engineering — introduce new functionality/changes applying modern techniques, generate a new improved system.
Legacy system ──reverse──▶ understand ──restructure/forward──▶ Re-engineered system (improved)How they relate to legacy systems
- Legacy systems are old, often critical systems built with outdated technology, poorly documented, and hard to maintain; yet they embody valuable business logic.
- Reverse engineering is the first step — it recovers the true structure/behaviour of the legacy system so that its logic is understood (essential when documentation is inadequate or the original developers are gone).
- Re-engineering then uses that understanding to renovate the legacy system — improving maintainability, moving to modern platforms/languages, fixing architectural weaknesses — while preserving the system's functional value, rather than rewriting from scratch (which is riskier and slower).
Key difference table
Aspect Reverse Engineering Re-engineering Goal Understand/analyze the system Improve/reconstruct the system Changes code? No Yes Direction Code → design (backwards) Design → new code (forwards, after reverse) Output Models/documentation An improved, modernized system Input Existing (often legacy) system Existing system (understood via reverse eng.) Typical use Documentation recovery, legacy analysis Modernization/restructuring of legacy software Summary: reverse engineering extracts knowledge from a legacy system without changing it; re-engineering uses that knowledge to rebuild/restructure the legacy system into a higher-quality, more maintainable one.
Coursify — Personal AI Course Generator
Struggling with a difficult subject or concept? Turn any engineering topic into a structured course with interactive lessons, quizzes, and research-backed explanations.