Software Engineering
What is Software Engineering
Цели урока
- Distinguish the craft of programming from the engineering discipline around it
- Name the real causes of project failure: requirements, communication, processes, not just code
- Know the core team roles (PM, dev, QA, DevOps, SRE) and what each one buys
- Understand why 70-80% of a system's cost lives in maintenance, not first delivery
- Recognize career tracks: IC, lead, staff, principal, manager
Предварительные знания
- Some hands-on programming experience in any language
- Comfort with the words function, variable, bug
- Curiosity about how real teams ship software at scale, not just textbook examples
In 1996, a $370 million rocket exploded because of one line of code. The code was correct - it just ended up in the wrong system. This is not a programmer's bug, it's an engineering failure. The difference between "writing code" and "building software systems" is the difference between knowing how to lay bricks and designing a skyscraper.
- **Startups**: 90% of projects fail not because of "bad code" but because of chaos in requirements and processes
- **Corporations**: Amazon deploys every 11.7 seconds - this is the result of a mature engineering culture, not just good programmers
- **Career impact**: the salary difference between a "coder" and an "engineer" is 2–3×, because an engineer solves business problems, not just writes functions
Engineering vs Coding
In 1996 the **Ariane 5** rocket exploded 37 seconds after launch. Cost - $370 million. Cause? A 16-bit integer overflow when converting a 64-bit float. The code worked perfectly - on **Ariane 4**. It was copied without analysing the new conditions. The programmer wrote correct code. The engineer should have asked: "Does this code fit the new system?"
**Coding** - writing instructions for a computer. **Software Engineering** - the discipline of creating software systems that work reliably, for a long time, and in a team. The difference is like laying bricks versus designing a building.
Frederick Brooks in the essay **"No Silver Bullet" (1986)** articulated a key observation: the main complexity of software is not in language syntax or compilation speed. Complexity lies in the very **nature of the problems**: requirements change, systems grow, people misunderstand each other.
Standish Group CHAOS Report
Since 1994 the Standish Group has published the CHAOS report on the fate of IT projects. The first report was shocking: **31%** of projects were cancelled, **53%** exceeded budget by twofold, only **16%** finished on time. By the 2020s the situation had improved, but still **~66%** of projects face serious problems. The #1 cause is not "bad code" but unclear requirements, lack of communication, and poor management.
| Aspect | Coding | Software Engineering |
|---|---|---|
| Scale | Script, utility | System of hundreds of modules |
| Team | 1 person | 10–1000 people |
| Lifetime | Days–weeks | Years–decades |
| Main challenge | Algorithm, syntax | Communication, complexity, change |
| Cost of error | Bug in a script | $370M rocket / data breach |
A good engineer is not the one who writes the cleverest code, but the one whose code **other people** can read, change, and evolve five years from now.
The Ariane 5 rocket exploded because of a bug in the code. Why is this an engineering problem, not a coding problem?
Software Development Life Cycle (SDLC)
If software engineering is not just coding, what does it consist of? The answer is the **Software Development Life Cycle (SDLC)** - a set of phases every project goes through. Different methodologies organise these phases differently, but the phases themselves are inevitable: analysis → design → implementation → testing → deployment → maintenance.
| Methodology | When it fits | Strengths | Weaknesses |
|---|---|---|---|
| Waterfall | Fixed requirements (government contracts, hardware) | Predictability, documentation | No feedback until the end |
| V-Model | Safety-critical (medical, aviation) | Every level is tested | Rigidity, expensive changes |
| Agile/Scrum | Startups, products, unclear requirements | Fast feedback, adaptability | Hard to plan a year ahead |
| DevOps | Mature teams, cloud-native | Continuous delivery, automation | Requires culture and infrastructure |
**Waterfall** (Winston Royce, 1970) - a linear sequence of phases. Royce described this model as an **anti-pattern**, but the industry took it literally. Result: teams spent a year writing requirements, a year coding, and then during testing discovered that the requirements were outdated.
**Agile Manifesto (2001)** was a response to Waterfall failures. Four values: individuals over processes, working software over comprehensive documentation, customer collaboration over contract negotiation, responding to change over following a plan.
**DevOps** (2009+) - the next evolution: the wall between Dev and Ops is broken down. CI/CD pipelines automate build, testing, and deployment. Amazon deploys to production **every 11.7 seconds**.
There is no "best" methodology. SpaceX uses elements of Agile for software and Waterfall for hardware. The choice depends on context: degree of uncertainty, cost of error, and team size.
A startup is building a mobile application. Requirements change every week after user testing. Which methodology fits best?
Software Quality: External and Internal
The user sees that the application is **slow** (external quality). The developer sees that the code is **spaghetti copy-paste** (internal quality). Both problems are real, but they are solved differently and have different visibility.
| External quality (user sees) | Internal quality (developer sees) |
|---|---|
| UX - interface usability | Readability - code reads like text |
| Performance - response speed | Testability - code is covered by tests |
| Reliability - system doesn't crash | Maintainability - changes don't break everything |
| Security - data is protected | Modularity - components are independent |
| Accessibility - available to everyone | Consistency - uniform patterns |
External quality **depends on** internal quality. Spaghetti code will sooner or later lead to slowdowns, bugs, and crashes. But internal quality is **invisible** to the business - which is why it is often sacrificed to meet deadlines.
In 1992 Ward Cunningham introduced the metaphor of **Technical Debt**. Like financial debt, it allows "borrowing" time now (cutting corners), but requires "interest" later (every change takes more and more time).
**Not all debt is bad.** Cunningham distinguished **deliberate** debt ("we know we're cutting corners, we'll come back and fix it") from **inadvertent** debt ("we wrote what we could, we don't know it's bad"). The first is a strategic decision. The second is a time bomb.
Boy Scout rule: leave the code **cleaner** than it was. No grand refactoring needed - every commit improves quality a little.
A team decides to copy 200 lines of code instead of refactoring in order to meet a deadline. The manager says: "We'll fix it later." What will happen?
Complexity: the Engineer's Main Enemy
Why is software so complex? Brooks in "No Silver Bullet" split complexity into two types. **Essential complexity** - the unavoidable complexity of the problem itself. A tax code is complex not because of bad code, but because taxes are a complex domain. **Accidental complexity** - complexity we **added ourselves**: poor architecture, bad tools, unnecessary abstractions.
**Conway's Law (1967)**: "Organisations which design systems are constrained to produce designs which are copies of the communication structures of these organisations." Four teams produce four services. Teams that don't communicate produce services that don't integrate well.
How is **complexity measured**? A few key metrics:
| Metric | What it measures | Good | Bad |
|---|---|---|---|
| Cyclomatic Complexity | Number of paths through a function (if/else/loop) | 1–10 | > 20 |
| Coupling | Dependency between modules | Loose | Tight |
| Cohesion | Internal cohesion within a module | High (on topic) | Low (mixed bag of functions) |
| Lines per function | Function size | < 30 lines | > 100 lines |
| Depth of inheritance | Depth of class hierarchy | 1–3 levels | > 5 levels |
**Coupling and Cohesion** - two sides of the same coin. A good module has **high cohesion** (does one thing well) and **low coupling** (minimally depends on others). If a `UserService` module contains email-sending logic, payment processing, and PDF generation - it has low cohesion.
Complexity grows **non-linearly**. A system of 10 modules can have 45 potential connections (n*(n-1)/2). Of 100 modules - 4950. Each new connection increases cognitive load on the developer.
Good code is maximally short code. Fewer lines = fewer bugs.
Good code is readable and maintainable code. Sometimes more lines make the intent clearer.
The one-liner `users.filter(u=>u.a>18&&u.s=='active'&&!u.d).map(u=>({...u,r:'premium'}))` is short but incomprehensible. A more verbose version with named variables and comments is longer, but any team member will understand and change it a year from now. Readability and maintainability beat brevity.
A developer complains: "Our project is complex because the business logic is convoluted - taxes, discounts, rules." What type of complexity is this?
Key Takeaways
- **Engineering ≠ coding**: code is ~20% of the work. The rest - requirements, architecture, testing, maintenance
- **SDLC - the life cycle**: Waterfall → V-Model → Agile → DevOps. There is no "best" methodology - only one that fits the context
- **Quality is dual**: external (user sees) and internal (developer sees). Technical debt links them: poor internal → poor external
- **Complexity is the main enemy**: essential (unavoidable) vs accidental (our fault). The engineer's goal is to minimise accidental complexity
- Remember Ariane 5? The line of code was perfect. The engineering process was not. Code without engineering is a rocket without a guidance system
What's next?
Software Engineering is the foundation. Specific engineering skills next:
- Requirements and Specifications — How to turn an idea into a precise description of a system
- Architectural Patterns — How to organise code at scale
Вопросы для размышления
- Consider a project that "failed". Was it a code problem or an engineering process problem?
- What technical debt exists in current projects? Is it deliberate or inadvertent?
- In designing Ariane 5, which SDLC phase would have prevented the explosion?
Связанные уроки
- prog-01-intro — Basic programming is a prerequisite for engineering discipline
- se-02 — Next lesson: practical development methodologies
- st-01-feedback-loops — Systems thinking is a key tool for every software engineer
- db-01-intro — Data design is the first major engineering decision in any project
- sd-01-intro