← Module 4: Software Engineering Project
Inquiry Question 1: How are large-scale software solutions developed and managed?
Apply code review and quality practices, including peer review, style guides, linters and static analysis
A focused answer to the HSC Software Engineering Module 4 dot point on code review. Pull request reviews, style guides, linters, static analysis, the worked example, and the traps markers look for.
Have a quick question? Jump to the Q&A page
What this dot point is asking
NESA wants you to describe how code review works in a software team, the mechanical tools that support it, and how the combination of human review and automated tools produces high-quality code.
The answer
Code review
A peer reviews every change before it is merged. In modern Git workflows, this happens on pull requests:
- The author opens a PR.
- Reviewers read the diff, leave inline comments, ask questions, request changes.
- The author replies or revises. Comments are resolved.
- When reviewers approve and automated checks pass, the PR can be merged.
What reviewers look for
- Correctness: does the code do what the PR says it does?
- Tests: are there tests for the change? Do they cover the edge cases?
- Security: are inputs validated, outputs encoded, queries parameterised?
- Maintainability: is the code clear? Are the names good? Is the structure consistent with the rest of the codebase?
- Design: is this the right approach? Are there simpler alternatives?
- Documentation: are docs updated? Are non-obvious decisions noted?
- Performance: any obvious hot spots? N+1 queries? Memory leaks?
Constructive review
Best practice from industry:
- Comment on the code, not the person. "This function could be clearer", not "you wrote unclear code".
- Distinguish blocking issues from suggestions. Use prefixes like
[blocking]or[nit]. - Ask questions rather than make pronouncements. "Why this approach?" surfaces assumptions.
- Approve when ready. Holding approval for minor preferences slows everything down.
- Authors: take feedback seriously, push back when warranted, do not take it personally.
Style guides
A document (or shared linter config) describing how the team writes code:
- Naming conventions (snake_case for Python variables, camelCase for JavaScript).
- File and folder structure.
- Comment style.
- Error handling patterns.
- Import order.
Examples: PEP 8 for Python, Airbnb JavaScript Style Guide, Google's various style guides.
Linters and formatters
Automated tools that enforce style and catch common mistakes:
| Language | Linter | Formatter |
|---|---|---|
| Python | ruff (or flake8 + pylint) | black, ruff format |
| JavaScript/TypeScript | eslint | prettier |
| Go | golangci-lint | gofmt |
| Java | Checkstyle | google-java-format |
| Rust | clippy | rustfmt |
Run automatically in CI on every PR. Failed lint blocks the merge.
# A ruff configuration in pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "B", "I", "S", "C90"]
# E = pycodestyle errors
# F = pyflakes (unused imports, undefined names)
# B = bugbear (common bug patterns)
# I = import order
# S = security (bandit)
# C90 = complexity (McCabe)
Static analysis
Goes deeper than linting. Analyses the code structure without running it.
- Type checkers: mypy (Python), TypeScript, Flow. Catch type mismatches and missing null checks.
- Security scanners: Semgrep, SonarQube, Snyk Code. Match common vulnerability patterns.
- Complexity analysers: McCabe complexity, cyclomatic complexity, identify functions that should be refactored.
- Dead code detectors: identify unreachable code and unused imports.
Run in CI alongside tests.
Pre-commit hooks
Run linters and formatters automatically on every commit, before the change leaves the developer's machine. Saves a round trip with CI.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.0
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
hooks:
- id: mypy
Architecture decision records (ADRs)
For decisions that shape the codebase, write a short record:
# ADR 0007: Use PostgreSQL not MongoDB
## Status
Accepted, 2026-05-15
## Context
We need a database. The team has more SQL experience than NoSQL.
## Decision
Use PostgreSQL 15.
## Consequences
- Strong consistency by default.
- Mature tooling (psql, pgAdmin).
- The team must design relational schemas, including for semi-structured
data (use jsonb columns where needed).
ADRs preserve the why behind technical choices, so future maintainers can revisit them with full context.
Metrics
Some teams track:
- Time to review: median hours from PR open to first review.
- Time to merge: median hours from PR open to merge.
- Review thoroughness: comments per 100 lines of diff.
- Coverage: test coverage percentage.
- Lint debt: open lint errors.
Use metrics as signals to investigate, not targets to optimise (Goodhart's law).
Past exam questions, worked
Real questions from past NESA papers on this dot point, with our answer explainer.
2024 HSC5 marksExplain the purpose of code review in a software project. Describe two complementary practices that improve code quality alongside code review.Show worked answer →
Code review is the practice of having another developer read and approve every change before it is merged into the main branch. The reviewer checks for correctness, security, style, maintainability, and adherence to team conventions. Review is conducted on a pull request (PR), with line-by-line comments and an explicit approve or request-changes decision.
Purposes:
- Catch bugs before they reach main, while the change is small and fresh.
- Share knowledge across the team. Reviewing teaches both reviewer and author.
- Maintain consistency. Reviewers enforce the team's standards.
- Provide an audit trail. Every change has a recorded discussion attached.
Complementary practice 1: linters and formatters. Tools like ruff (Python), eslint (JavaScript), prettier and black automate enforcement of style rules and catch common mistakes. The team configures the linter once, and every commit is checked in CI. This frees humans from arguing about formatting and lets the code review focus on logic and design.
Complementary practice 2: static analysis. Tools like mypy (Python type checking), TypeScript, SonarQube and Semgrep analyse the code without running it. They catch type mismatches, unreachable code, common security patterns (hardcoded secrets, missing null checks), and complexity hotspots. Static analysis catches systematic issues that humans tire of catching.
Together, linters and static analysis handle the mechanical issues so code review can focus on the higher-value questions: is this the right design? Have edge cases been considered? Does it match user needs?
Markers reward a clear definition of code review, at least two distinct purposes, and two complementary practices (not just two linters). Best answers note that reviews are most effective when freed from mechanical issues by tooling.
Related dot points
- Use version control to manage source code, including commits, branches, merges, pull requests and remote repositories
A focused answer to the HSC Software Engineering Module 4 dot point on Git. Commits, branches, merges, pull requests, the worked feature-branch workflow, and the traps markers look for.
- Describe testing strategies, including unit testing, integration testing, system testing and user acceptance testing
A focused answer to the HSC Software Engineering Module 4 dot point on testing. Unit, integration, system, UAT, the test pyramid, test-driven development, the worked Python example, and the traps markers look for.
- Set up continuous integration and deployment pipelines that build, test and release software automatically
A focused answer to the HSC Software Engineering Module 4 dot point on CI/CD. Build, test, deploy automation, GitHub Actions, the worked pipeline example, and the traps markers look for.