# [NPRG035] Zkouška z C#, termín 26. 1. 2026: co tam bylo

Ahoj, minulý termín jsem psal zkoušku z C# a sepisuju, co si pamatuju, ať mají další ročníky představu, co je čeká. Zadání tu nekopíruju a kód je přepsaný z hlavy. Názvy a detaily se můžou lišit, princip by ale měl sedět.

## Formát

- 2 strany A4, celkem **10 otázek**
- Odpovídá se na zvláštní papír se jménem a fotkou, každý list se podepisuje a čísluje (i/N)
- Otázky 1–8 jsou typu „co program vypíše a proč“. Několik otázek vždy sdílí společný kód (bloky A, B, C).
- Otázky 9–10 jsou návrhové (napsat a zdůvodnit kód)
- Skoro všude chtějí **detailní vysvětlení**, samotný výstup nestačí

---

## Blok A (otázky 1–2): `using var` a `IDisposable`

Byla tam třída implementující `IDisposable`, která má `init`-only vlastnost `X`. Metoda `m()` vypíše název metody a hodnotu X, `Dispose()` vypíše „Dispose“ a hodnotu X.

Hlavní program (top-level statements) vypadal zhruba takhle:

```csharp
using var a = new A { X = 6 };
a.m();
{
    using var b = new A { X = 7 };
    b.m();
}
Console.WriteLine("end");
```

- **Otázka 1:** Co program vypíše? Detailně vysvětlit.
- **Otázka 2:** Přepsat hlavní program **bez použití `using`** tak, aby se choval úplně stejně.

---

## Blok B (otázky 3–4): struct

Byl tam `struct Point`:
- jedno veřejné pole `int X`,
- read-only vlastnost, která vrací X na druhou (počítaná, bez backing fieldu),
- konstruktor s parametry `(int x, int y)`, který nastaví jen X,
- **statická** metoda `Reset(Point p)`, která nastaví `p.X = 100`,
- **instanční** metoda `Update()`, která zvýší X o 1.

V `Main` (ve zvláštní třídě):

```csharp
Point p1 = new Point(5, 10);
p1.Update();
Console.WriteLine($"X: {p1.X}");

Point.Reset(p1);
Console.WriteLine($"X: {p1.X}");
```

- **Otázka 3:** Co se vypíše na standardní výstup? Detailně vysvětlit proč.
- **Otázka 4:** Detailně vysvětlit, jak velká je proměnná `p1` a jakou má strukturu v paměti. Dál jak velká je instance `Point` a jak souvisí instance `Point` se samotnou proměnnou `p1`.

---

## Otázka 5: samostatná

Krátký kód zhruba v tomhle duchu:

```csharp
int x = 13;
object o = x;
var y = (long) o;
Console.WriteLine(y);
```

Otázka: co program vypíše a proč, a k tomu detailně vysvětlit, **co přesně bude obsahem proměnné `o`** a proč.

---

## Blok C (otázky 6–8): interface, virtual, abstract, `new`

Hierarchie (názvy jsem změnil):

- interface `I` s jedinou metodou `int f()`
- třída `C : I`, kde `f()` je obyčejná (nevirtuální) metoda a vrací 1
- abstraktní třída `A : C, I` (interface je **znovu uvedený**), která má `public abstract int f()`
- `sealed` třída `B : A`, která má `public override int f()` a vrací 2
- třída `D : C`, která má `public new int f()` a vrací 3 (interface znovu neuvádí)

Program:

```csharp
C c = new B();
Console.WriteLine(((I) c).f());
Console.WriteLine(((A) c).f());
Console.WriteLine(((D) c).f());
```

- **Otázka 6:** Co se vypíše na 1. řádku? Jako součást vysvětlení **nakreslit interfacovou tabulku metod** pro interface `I` u tříd A, B, C, D.
- **Otázka 7:** Co se vypíše na 2. řádku? Jako součást vysvětlení **nakreslit VMT** tříd A, B, C, D.
- **Otázka 8:** Co se vypíše na 3. řádku? Ve vysvětlení se dá navázat na předchozí otázku.

---

## Otázka 9: návrh loggeru

Navrhnout a implementovat třídu `FileLogger` s metodou `Log`, která zapíše předaný string do souboru.

- Metoda zároveň dostane **úroveň důležitosti** zprávy. Zatím jen tři úrovně: info, warning, error.
- Každé volání přidá do souboru **jeden řádek** ve formátu `úroveň: zpráva` (úroveň malými písmeny, dvojtečka, mezera, text).
- Do budoucna se počítá s dalšími loggery (jako příklad uvedli `JsonLogger`), které musí být **z pohledu kódu, který loguje, zaměnitelné**. Pro JsonLogger stačí kostra, tj. deklarace metod a vlastností bez těl.
- Nakonec **vysvětlit vhodnost a výhody celého návrhu**.

---

## Otázka 10: logování v existující třídě

Dostali jsme `record class Character` se třemi vlastnostmi:
- `MaxHealthPoints` (int, get/set)
- `HealthPercentage` (double, get/set)
- `HealthPoints` (int): getter vrací procento × max přetypované na int, setter přepočítá procento jako hodnota / max

Úkol: pomocí návrhu z otázky 9 doplnit logování. Postava má zalogovat **info**, když jí zdraví klesne **pod 50 %**. Opět vysvětlit vhodnost a výhody návrhu.

Během zkoušky padlo upřesnění, že se má logovat **vždy, když je zdraví ≤ 50 %**. Pokud vám to nebude jasné, doptejte se.

---

## Obecné dojmy a rady

- Hodně se zkouší, co se děje „pod kapotou“: paměť, hodnotové a referenční typy, VMT, interface mapy.
- Připravte se, že budete VMT a interfacové tabulky **kreslit**, ne jen popisovat.
- U „co to vypíše“ otázek počítejte i s tím, že program nemusí doběhnout normálně.
- U návrhových otázek je důležité zdůvodnění, ne jen funkční kód.
