Skip to content

Commit d1890b8

Browse files
committed
Complete expert module parity across languages
1 parent c69fe64 commit d1890b8

64 files changed

Lines changed: 2745 additions & 37 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

LANGUAGE_PARITY_MATRIX.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This matrix tracks module and checkpoint parity across C++, C#, Go, and Python.
44

55
- Canonical order is defined by the C++ track.
6-
- Current priority is to extend checkpoint parity beyond `02-core` without fragmenting the curriculum.
6+
- Current priority is to extend checkpoint parity beyond `02-core` now that module parity reaches `04-expert` across all active tracks.
77
- Status labels:
88
- `Done`: module implemented with example, exercises, and README.
99
- `Planned`: module not implemented yet, already queued in order.
@@ -42,9 +42,9 @@ Current parity progress in non-C++ tracks:
4242

4343
Current parity progress in non-C++ tracks:
4444

45-
- C#: `5/5` modules complete in `03-advanced`
46-
- Go: `5/5` modules complete in `03-advanced`
47-
- Python: `5/5` modules complete in `03-advanced`
45+
- C#: `5/5` modules complete in `03-advanced`, `5/5` in `04-expert`
46+
- Go: `5/5` modules complete in `03-advanced`, `5/5` in `04-expert`
47+
- Python: `5/5` modules complete in `03-advanced`, `5/5` in `04-expert`
4848

4949
### Advanced (`03-advanced`) - Current Expansion Queue
5050

@@ -56,17 +56,17 @@ Current parity progress in non-C++ tracks:
5656
| 4 | inheritance-and-polymorphism | Done | Done | Done | Done |
5757
| 5 | templates-basics | Done | Done | Done | Done |
5858

59-
`04-expert` has started in C# with `memory-management-and-raii`, `concurrency-basics`, and `modularization-and-build-structure`; broader expert parity is still planned.
59+
`04-expert` is now implemented across C#, Go, and Python; the next parity target is projects and assessments beyond `02-core`.
6060

61-
### Expert (`04-expert`) - Early Expansion
61+
### Expert (`04-expert`)
6262

6363
| Order | Module | C++ | C# | Go | Python |
6464
| --- | --- | --- | --- | --- | --- |
65-
| 1 | memory-management-and-raii | Done | Done | Planned | Planned |
66-
| 2 | smart-pointers-in-depth | Done | Planned | Planned | Planned |
67-
| 3 | concurrency-basics | Done | Done | Planned | Planned |
68-
| 4 | performance-and-profiling-basics | Done | Planned | Planned | Planned |
69-
| 5 | modularization-and-build-structure | Done | Done | Planned | Planned |
65+
| 1 | memory-management-and-raii | Done | Done | Done | Done |
66+
| 2 | smart-pointers-in-depth | Done | Done | Done | Done |
67+
| 3 | concurrency-basics | Done | Done | Done | Done |
68+
| 4 | performance-and-profiling-basics | Done | Done | Done | Done |
69+
| 5 | modularization-and-build-structure | Done | Done | Done | Done |
7070

7171
## Checkpoint Parity
7272

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ This repository teaches programming through small runnable examples and focused
2525
| Language | Current Levels | Coverage | Track Status |
2626
| --- | --- | --- | --- |
2727
| C++ | 00-setup, 01-foundations, 02-core, 03-advanced, 04-expert | Foundations, Core, Advanced, Expert, projects, assessments | Most complete and primary track |
28-
| C# | 01-foundations, 02-core, 03-advanced, 04-expert (partial) | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 3/5 expert modules, 2/4 projects, 2/4 assessments | Advanced parity complete, expert rollout in progress |
29-
| Go | 01-foundations, 02-core, 03-advanced | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 2/4 projects, 2/4 assessments | Advanced parity complete, checkpoints started |
30-
| Python | 01-foundations, 02-core, 03-advanced | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 2/4 projects, 2/4 assessments | Advanced parity complete, checkpoints started |
28+
| C# | 01-foundations, 02-core, 03-advanced, 04-expert | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 5/5 expert modules, 2/4 projects, 2/4 assessments | Module parity complete through expert |
29+
| Go | 01-foundations, 02-core, 03-advanced, 04-expert | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 5/5 expert modules, 2/4 projects, 2/4 assessments | Module parity complete through expert |
30+
| Python | 01-foundations, 02-core, 03-advanced, 04-expert | 8/8 foundations modules, 6/6 core modules, 5/5 advanced modules, 5/5 expert modules, 2/4 projects, 2/4 assessments | Module parity complete through expert |
3131

3232
Parity planning reference: [LANGUAGE_PARITY_MATRIX.md](LANGUAGE_PARITY_MATRIX.md)
3333

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# C# 04 Expert
22

3-
This level is rolling out incrementally in C# while the rest of expert parity is still in progress.
3+
This level is now fully implemented in C#.
44

55
## Module Order
66

77
1. [memory-management-and-raii](./memory-management-and-raii/README.md)
8-
2. smart-pointers-in-depth (planned, language-adapted)
8+
2. [smart-pointers-in-depth](./smart-pointers-in-depth/README.md)
99
3. [concurrency-basics](./concurrency-basics/README.md)
10-
4. performance-and-profiling-basics (planned)
10+
4. [performance-and-profiling-basics](./performance-and-profiling-basics/README.md)
1111
5. [modularization-and-build-structure](./modularization-and-build-structure/README.md)
1212

1313
Track progress in [../CHECKLIST.md](../CHECKLIST.md).
1414

1515
## Study Tip
1616

17-
Use this level to move from deterministic cleanup into concurrent coordination and then into modular project structure before tackling performance topics.
17+
Use this level to move from deterministic cleanup into ownership modeling, concurrent coordination, performance measurement, and modular project structure.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Performance and Profiling Basics (C#)
2+
3+
This module introduces simple measurement and optimization patterns in C#.
4+
5+
## Quick Run
6+
7+
~~~bash
8+
dotnet run --project example/performance-and-profiling-basics-example.csproj
9+
~~~
10+
11+
## Topics Covered
12+
13+
- Measuring elapsed time with `Stopwatch`.
14+
- Comparing two implementations on the same workload.
15+
- Reducing allocations with `StringBuilder` or pre-sized collections.
16+
- Avoiding conclusions from noisy one-off timings.
17+
18+
## Common Pitfalls
19+
20+
- Timing workloads that are too small to compare meaningfully.
21+
- Mixing data generation time with the code under test.
22+
- Treating a single faster run as a final truth.
23+
- Optimizing without understanding algorithmic cost first.
24+
25+
## Exercise Focus
26+
27+
- exercises/01.cs: compare string concatenation with `StringBuilder`.
28+
- exercises/02.cs: compare `List<T>` growth with and without initial capacity.
29+
30+
### Exercise Specs
31+
32+
1. exercises/01.cs
33+
- Input: line count.
34+
- Output: elapsed ticks for both string-building approaches.
35+
- Edge cases: zero lines; very small workloads produce noisy timings.
36+
37+
2. exercises/02.cs
38+
- Input: element count.
39+
- Output: elapsed ticks for list fill with and without preset capacity.
40+
- Edge cases: zero count; small sizes with little visible difference.
41+
42+
## Checkpoint
43+
44+
- [ ] I can measure work with `Stopwatch`.
45+
- [ ] I can compare two implementations on the same input fairly.
46+
- [ ] I can explain why pre-sizing or reducing allocations can help.
47+
- [ ] I completed exercises/01.cs.
48+
- [ ] I completed exercises/02.cs.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Example purpose: compare a couple of small optimization choices with Stopwatch.
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Text;
7+
8+
class Program
9+
{
10+
static void Main()
11+
{
12+
// Program flow: measure two paired implementations on the same workload size.
13+
const int lineCount = 4000;
14+
long concatTicks = Measure(() => BuildWithConcatenation(lineCount));
15+
long builderTicks = Measure(() => BuildWithStringBuilder(lineCount));
16+
17+
Console.WriteLine($"String concatenation ticks: {concatTicks}");
18+
Console.WriteLine($"StringBuilder ticks: {builderTicks}");
19+
20+
const int itemCount = 200000;
21+
long noCapacityTicks = Measure(() => FillWithoutCapacity(itemCount));
22+
long withCapacityTicks = Measure(() => FillWithCapacity(itemCount));
23+
24+
// Intent: final output keeps the comparison direct and easy to verify.
25+
Console.WriteLine($"List fill without capacity ticks: {noCapacityTicks}");
26+
Console.WriteLine($"List fill with capacity ticks: {withCapacityTicks}");
27+
}
28+
29+
static long Measure(Action action)
30+
{
31+
Stopwatch stopwatch = Stopwatch.StartNew();
32+
action();
33+
stopwatch.Stop();
34+
return stopwatch.ElapsedTicks;
35+
}
36+
37+
static string BuildWithConcatenation(int lineCount)
38+
{
39+
string result = string.Empty;
40+
for (int index = 0; index < lineCount; index++)
41+
{
42+
result += $"row-{index};";
43+
}
44+
45+
return result;
46+
}
47+
48+
static string BuildWithStringBuilder(int lineCount)
49+
{
50+
StringBuilder builder = new StringBuilder(lineCount * 8);
51+
for (int index = 0; index < lineCount; index++)
52+
{
53+
builder.Append("row-");
54+
builder.Append(index);
55+
builder.Append(';');
56+
}
57+
58+
return builder.ToString();
59+
}
60+
61+
static List<int> FillWithoutCapacity(int itemCount)
62+
{
63+
List<int> values = new List<int>();
64+
for (int index = 0; index < itemCount; index++)
65+
{
66+
values.Add(index);
67+
}
68+
69+
return values;
70+
}
71+
72+
static List<int> FillWithCapacity(int itemCount)
73+
{
74+
List<int> values = new List<int>(itemCount);
75+
for (int index = 0; index < itemCount; index++)
76+
{
77+
values.Add(index);
78+
}
79+
80+
return values;
81+
}
82+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>disable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
8+
</PropertyGroup>
9+
<ItemGroup>
10+
<Compile Include="main.cs" />
11+
</ItemGroup>
12+
</Project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.Text;
4+
5+
class Program
6+
{
7+
static void Main()
8+
{
9+
Console.Write("Line count: ");
10+
if (!int.TryParse(Console.ReadLine(), out int lineCount))
11+
{
12+
Console.WriteLine("Invalid line count.");
13+
return;
14+
}
15+
16+
if (lineCount < 0)
17+
{
18+
Console.WriteLine("Line count cannot be negative.");
19+
return;
20+
}
21+
22+
long concatTicks = Measure(() => BuildWithConcatenation(lineCount));
23+
long builderTicks = Measure(() => BuildWithBuilder(lineCount));
24+
25+
Console.WriteLine($"Concatenation ticks: {concatTicks}");
26+
Console.WriteLine($"StringBuilder ticks: {builderTicks}");
27+
}
28+
29+
static long Measure(Action action)
30+
{
31+
Stopwatch stopwatch = Stopwatch.StartNew();
32+
action();
33+
stopwatch.Stop();
34+
return stopwatch.ElapsedTicks;
35+
}
36+
37+
static string BuildWithConcatenation(int lineCount)
38+
{
39+
string text = string.Empty;
40+
for (int index = 0; index < lineCount; index++)
41+
{
42+
text += $"item-{index};";
43+
}
44+
45+
return text;
46+
}
47+
48+
static string BuildWithBuilder(int lineCount)
49+
{
50+
StringBuilder builder = new StringBuilder(lineCount * 8);
51+
for (int index = 0; index < lineCount; index++)
52+
{
53+
builder.Append("item-");
54+
builder.Append(index);
55+
builder.Append(';');
56+
}
57+
58+
return builder.ToString();
59+
}
60+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
5+
class Program
6+
{
7+
static void Main()
8+
{
9+
Console.Write("Element count: ");
10+
if (!int.TryParse(Console.ReadLine(), out int elementCount))
11+
{
12+
Console.WriteLine("Invalid element count.");
13+
return;
14+
}
15+
16+
if (elementCount < 0)
17+
{
18+
Console.WriteLine("Element count cannot be negative.");
19+
return;
20+
}
21+
22+
long noCapacityTicks = Measure(() => FillWithoutCapacity(elementCount));
23+
long withCapacityTicks = Measure(() => FillWithCapacity(elementCount));
24+
25+
Console.WriteLine($"Without capacity ticks: {noCapacityTicks}");
26+
Console.WriteLine($"With capacity ticks: {withCapacityTicks}");
27+
}
28+
29+
static long Measure(Action action)
30+
{
31+
Stopwatch stopwatch = Stopwatch.StartNew();
32+
action();
33+
stopwatch.Stop();
34+
return stopwatch.ElapsedTicks;
35+
}
36+
37+
static List<int> FillWithoutCapacity(int elementCount)
38+
{
39+
List<int> values = new List<int>();
40+
for (int index = 0; index < elementCount; index++)
41+
{
42+
values.Add(index);
43+
}
44+
45+
return values;
46+
}
47+
48+
static List<int> FillWithCapacity(int elementCount)
49+
{
50+
List<int> values = new List<int>(elementCount);
51+
for (int index = 0; index < elementCount; index++)
52+
{
53+
values.Add(index);
54+
}
55+
56+
return values;
57+
}
58+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Smart Pointers in Depth (C#)
2+
3+
This module adapts smart pointer ideas to managed references, ownership transfer, and weak observation in C#.
4+
5+
## Quick Run
6+
7+
~~~bash
8+
dotnet run --project example/smart-pointers-in-depth-example.csproj
9+
~~~
10+
11+
## Topics Covered
12+
13+
- Treating nullable references as explicit ownership slots.
14+
- Moving an owned reference by transferring it and clearing the original holder.
15+
- Using `WeakReference<T>` for non-owning observation.
16+
- Distinguishing strong lifetime responsibility from temporary access.
17+
18+
## Common Pitfalls
19+
20+
- Assuming the garbage collector makes ownership design irrelevant.
21+
- Keeping accidental strong references in caches or observers.
22+
- Using `WeakReference<T>` where a normal strong dependency is simpler.
23+
- Forgetting to clear the old owner after a transfer.
24+
25+
## Exercise Focus
26+
27+
- exercises/01.cs: move an owned document reference between holders.
28+
- exercises/02.cs: observe cache entries through `WeakReference<T>`.
29+
30+
### Exercise Specs
31+
32+
1. exercises/01.cs
33+
- Input: none.
34+
- Output: ownership transfer logs before and after moving.
35+
- Edge cases: moving from an empty owner; destination already holding another object.
36+
37+
2. exercises/02.cs
38+
- Input: none.
39+
- Output: alive/expired cache lookup logs.
40+
- Edge cases: expired weak reference; cache miss.
41+
42+
## Checkpoint
43+
44+
- [ ] I can explain strong vs weak references in C#.
45+
- [ ] I can model an ownership transfer by clearing the previous owner.
46+
- [ ] I can choose when a weak observer is appropriate.
47+
- [ ] I completed exercises/01.cs.
48+
- [ ] I completed exercises/02.cs.

0 commit comments

Comments
 (0)