Computational Thinking
The mental habits that turn a vague real-world problem into something a computer can solve — the foundation under all programming
Programming is not really about typing. It is about a particular way of thinking. Before you can write good code in any language, you have to develop a small set of mental habits that let you take a messy real-world problem and break it down into something concrete enough for a computer to handle.
That cluster of habits is called computational thinking, and it is the most transferable skill in this entire course. It applies to C#, but it also applies to JavaScript, Python, Excel formulas, SQL queries, even managing your inbox.
The four habits
That's the whole framework: decompose, recognize patterns, abstract, and design a step-by-step solution. The rest of this page is just examples.
Decomposition
Decomposition means taking a problem that is too big to think about all at once and breaking it into smaller subproblems.
Suppose someone says: "build me a system to track tasks."
That sentence is huge. There are dozens of decisions hidden in it: what is a task? Who owns it? When is it due? How is it stored? How do you list them?
A decomposed view looks more like:
Each box on the bottom row is a problem you actually know how to attack. The big box on top isn't. Decomposition is the bridge.
Pattern recognition
Once you've solved a few small problems, you start to notice when two problems are really the same problem with different names:
| Problem in words | Underlying pattern |
|---|---|
| Find the largest score in a class | Find the maximum of a list |
| Find the longest word in a sentence | Find the maximum of a list |
| Find the highest-paying job listing | Find the maximum of a list |
Three completely different domains. One underlying pattern: "go through a collection, remember the best one you've seen so far."
Programmers spend their whole careers building a personal library of recognized patterns. Every time you do, you stop having to invent that wheel.
Here is the "max of a list" pattern, in C#:
Once you know this pattern, you can apply it to longest word, warmest day, most expensive product — anything where "biggest / best of a collection" comes up.
Abstraction
Abstraction is the habit of ignoring details that don't matter for the problem at hand.
When you describe a task in a task tracker, you might say "a task has a title, a due date, and a status." That description ignores:
- The font the title is displayed in
- The number of pixels of padding around the due date
- The exact disk file the task is saved to
- Whether the task is stored as JSON, XML, or a database row
All of those things might matter somewhere, but they don't matter for modeling what a task is. By ignoring them, you can think clearly about the part that actually matters.
Whole programming-language features exist to support abstraction: classes, methods, interfaces, modules. We will meet all of them. But the habit comes first. You have to know what to ignore before you know what to model.
Algorithmic thinking
Finally, algorithmic thinking is the habit of being precise about steps. A computer cannot guess what you mean. If your instructions are vague, they will be wrong.
Try this exercise: write down, in words, exactly how to make a peanut butter sandwich, for someone who has never seen one.
A first attempt:
- Spread peanut butter on bread.
- Put another slice on top.
A more algorithmic version:
The second version is uglier, but it covers cases the first one doesn't: what if there's no bread? That kind of "are you sure?" question is exactly what bugs come from. Computers do not have common sense; you have to supply it.
In code, the same instinct shows up like this:
A vague programmer writes return a / b; and ships it. A
computationally-thinking programmer asks "what could b be?" and
covers the cases.
A worked example: counting unique words
Let's put all four habits together. Problem: "Given a string, tell me how many distinct words it contains."
Decomposition. What pieces are involved?
- Read the string.
- Split it into words.
- Throw away duplicates.
- Count what's left.
Pattern recognition. "Throw away duplicates and count" is the set pattern — every collection language has a tool for it.
Abstraction. What's a "word"? For now: a sequence of letters separated by whitespace. Ignore punctuation. Ignore upper/lower case differences. Those decisions are the model.
Algorithmic thinking. What about empty input? A string of only spaces? We should make those return zero, not crash.
Here is the program:
Trace the execution mentally:
Each habit shows up:
- Decomposition: split, normalize, dedupe, count — four small steps instead of one big "count unique words".
- Pattern recognition: "set of strings" is the right tool.
- Abstraction: we chose what counts as a word.
- Algorithmic thinking: empty and whitespace inputs are handled deliberately.
Practice
Write a program that reads a hard-coded array int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; and prints the sum of its even numbers.
The expected output is exactly:
sum of evens = 30
Apply computational thinking:
- Decompose: loop over the numbers, decide if each is even, accumulate.
- Pattern: this is the "filter + sum" pattern.
- Abstraction: ignore odd numbers entirely.
- Algorithm: be explicit about starting the sum at
0.
Test your understanding
Which of these is the best example of abstraction?
Writing very short variable names
Using fewer comments
Deciding that, for your task tracker, a task is just "title + due date + status", and ignoring colors, fonts, file formats, and disk layout
Always using var instead of a full type
Two problems — "find the longest sentence in a paragraph" and "find the most expensive product in a catalog" — share the same underlying solution shape. What is the name for noticing that?
Decomposition
Abstraction
Pattern recognition
Refactoring