Přednáška: Čtvrtek, 10:40, S3 (Pavel Ježek)
Cvičení:
Pondělí, 14:00, SW2 (Radek Zikmund)
Čtvrtek, 12:20, SW2 (Jan Pacovský)
Čtvrtek, 14:00, SW2 (Filip Kliber)
Čtvrtek, 17:20, SW2 (Pavel Ježek)
Stránka v SIS: NPRG038
Zakončení: Zkouška a zápočet
Table of contents
- Organizace předmětu
- Materiály z přednášek
- Náplň cvičení
- Informace o zkoušce
- Informace o zápočtu
- Uznávání povinností z minulých let
[in English] This page contains information for czech students of the Advanced C# Programming course. For english version, switch the language in the page header.
Organizace předmětu
Materiály z přednášek
1. Přednáška
- Obecné informace k předmětu a přehled ostatních .NET předmětů
- Informace o zápočtu a zkoušce
- Přiřaditelnosti typů
- Implicitní/Explicitní konverze v C#
- Konverze mezi typy v rámci dědičnosti
- Konverze mezi číselnými typy
- Boxing/Unboxing
- Vlastní konverze (pomocí metody, pomocí operátoru)
- Extension metody
- Fluent syntax
- Maďarská notace
Materiály
2. Přednáška
- Přetěžování metod
- Pravidla pro výběr metody za překladu
- Příklady komplikovanějších situací i s konverzemi
- Generické metody (a alternativy; příklad s funkcí
Max
) - Srovnání s generickými metodami v C++ (šablony)
- Pravidla implicitní specializace typových parametrů při volání generických metod
Materiály
3. Přednáška
- Pokračování generických metod, překlad generické metody do CIL kódu a pak specializace JITem za runtime, výběr metod při překladu
- Rozdíly oproti C++ šablonám při generování instrukce volání metod
- Duck typing v C#, C++ a Python a klíčové slovo
dynamic
- Omezení (constraint) na typový argument, klíčové slovo
where
- Rozdíl mezi
void m(I1 i)
avoid m<T>(T t) where T : I1
- Implementace metody
Max<T>
- Generické extension metody
- Generické typy, statické proměnné v generických typech
- Generické metody v generických typech
- Více constraints u generických typů
Materiály
4. Přednáška
- Připomenutí interface, interfacové tabulky a implementace interface metodami, typ implementující interface vyžadující stejné metody
- explicitní implementace metod interface, generický interface
- C#10/11:
static abstract
metody v interface a jejich volání v generických kontextech,static virtual
metody v interface - statický abstraktní operátor v interface a NET7.0 interface jako podpora pro generické čísla (
INumberBase
,IAdditionOperator
, atp. vSystem.Numerics
) - variance (kovariance, kontravariance, invariance), kovariance polí referenčního typu, kovariance podle návratové hodnoty virtuálních metod
Materiály
5. Přednáška
- variance (kovariance, kontravariance, invariance), generické typy (s typovým parametrem T) by-default invariantní (dle T)
- variantnost generických interfaces,
<out T>
(kovariance),<in T>
(kontravariance), interfaceIList<T>
,IReadOnlyList<out T>
- explicitní přetypování mezi různými interfaces, variantnost pouze u interfaces referenčních typů
IComparer<in T>
ICollection<T>
,IReadOnlyCollection<out T>
,IEnumerable<out T>
,IEnumerator<out T>
a negenerické varianty
Materiály
6. Přednáška
- jmenné prostory (
namespace
), file-scoped namespace - vnořené typy, viditelnost vnořených typů a srovnání s C++
friend
, viditelnost metod při implementaci vnořených interface s různou viditelností - implementace
IEnumerator
jako privátní vnořená třída (implementační detail), sémantika vlastností a metod enumerátoru,IEnumerator<T>
implementujícíIDisposable
- Modifikace kolekce během enumerace (nepodporované, ale detekovatelné)
foreach
cyklus a jeho implementace (+ duck-typing), výkonnostní rozdíl meziforeach
afor
nadIList
aforeach
přes poleIEnumerator
jakostruct
Materiály
7. Přednáška
- Motivační příklad k iterátorovým metodám,
yield return
, překlad iterátorové metody, generování stavového automatu,yield break
IEnumerable<T>.ToList
,IEnumerable<T>.ToArray
,LinkedList<T>
,new A{}
a metodaAdd
(pomocí duck-typing), concurrent modifikace lazy evaluace kolekce
Materiály
8. Přednáška
- Vracení
IEnumerable<T>
z iterátorové metody a optimalizace, výjimky v iterátorových metodách - delegáti,
delegate
,System.Delegate
, přiřaditelnost delegátů, cachování instancí delegátů, generický delegát, univerzální/přirození delegáti (Func
,Action
,Predicate
)
Materiály
9. Přednáška
- Reflexe (reflection),
System.Type
,typeof
,GetType
,System.Reflection.Assembly
,MethodInfo.Invoke
- Benchmark rychlosti volání přes reflection, voláním skrz delegáty a přímým voláním
- serializace, formát JSON,
JsonSerializer
, deep cloning aobject.MemberwiseClone
(shallow copy) - iterátorové metody jako implementace coroutines
Materiály
10.1 Přednáška
- statické lambda funkce a anonymní metody, type interence při přiřazování lambda funkce do delegáta
- Databázová tabulka jako kolekce řádků, SQL query a Language Integrated Queries (LINQ)
- Transformace LINQ syntaxe do volání metod
- LINQ to * (příklad na LINQ to Creatures, LINQ to Nothing)
- LINQ to Objects a implementace LINQ metod, eager vs. lazy evaluace a (ne)optimalizace dotazů
Materiály
10.2 Přednáška
- Nestatické lambda funkce, vázané a volné proměnné, closure, lambda funkce v C++ a capture-by-value, capture-by-reference
- Implementace lambda funkcí v C#,
Scope
(DisplayClass
)
Materiály
11. Přednáška
- Transformace scope do
DisplayClass
při vyrobení lambda funkce + příklad zachytávání proměnných - Vícevláknové programování, vlákno, crash-course do železničního zabezpečovacího zařízení a implementace v C# jako coroutine implementovaná iterátorovými metodami (cooperativní přepínání úloh)
- Výhody a nevýhody této implementace,
Thread.Sleep
,Thread.CurrentThread
,Thread.ManagedThreadId
, vyrobení instance třídyThread
aThread.Start
, context switch overhead Thread.State
,Thread.Yield
,Thread.Join
, připomenutí race-condition, thread-safety
Materiály
12. Přednáška
- thread-pool (
ThreadPool
) asynchronní,Parallel
(Invoke
,For
,ForEach
) synchronní (využíváThreadPool
) - future (
Task<T>
),Task.Result
,Task.WaitAll
,Task.WaitAny
, promise (TaskCompletionSource
) - vyhazování
AggregateException
při voláníWait
na zrušeném promise CancellationToken
(kooperativní zrušení),Task.FromCancelled
,CancellationTokenSource
- kritická sekce, vzájemné vyloučení (mutual exclusion), zámky, sync-block, třída
Monitor
(metodyMonitor.Enter
aMonitor.Exit
, příkazlock
)
Materiály
13. Přednáška
- připomenutí future (
Task<T>
) a promise (TaskCompletionSource
) Task<T>
(vyrobený pomocínew
) jako future+promise dohromady a implementace,CancellationToken.ThrowIfCancellationRequested
Task.Factory.StartNew
a race-conditions uTask.Start
,ThreadPool
aTask.Run
- příklad se zahlcením
ThreadPool
a rozdíl sParallel.For
Task.ContinueWith
(task continuations) a graf závislostí tasků,TaskContinuationOptions
,Task.Factory.ContinueWhenAll
/ContinueWhenAny
,Task.Delay
,Task.WhenAll
/WhenAny
- problém s kaskádováním kódu při používání task continuations a nepraktické řešení pomocí iterátorových metod
- lokální funkce (pojmenovaná lambda funkce), více na 11ET přednášce
- řešení pomocí asynchronní metody (
async
) a klíčového slovaawait
s možností vracet hodnoty (return
) - problém s ignorováním výsledku (
Task
) asynchronní metody pokud vrací výjimku a problém sAggregateException
obsahujícíOperationCancelledException
, kterýawait
rozbalí automaticky (i kdyby jich tam bylo více, pak se zbytek ignoruje) - nefungující zamykání v asynchronní metodě (
lock
ani syntakticky nejde) a řešení pomocí semaforu (SemaphoreSlim
aSemaphoreSlim.WaitAsync
) Semaphore
a jiní potomci třídyWaitHandle
, které neslouží pro synchronizaci mezi vlákny (ale mezi procesy)
Materiály
14. Přednáška (nad rámec zkoušky)
- Synchronizační primitiva
SemaphoreSlim
,CountdownEvent
- condition variable jako součást sync-blocku a celkově ve třídě
Monitor
(Monitor.Wait
,Monitor.Pulse
) - implementace a sémantika condition variable, čekání na podmínku, důvody nutnosti zamykání při používání condition variable, spurious wakeup
- producent/konzument problém a implementace
- TLS (thread local storage),
[ThreadStatic]
atribut,ThreadLocal
třída s lepší možností inicializace - threading-model (obecně), threading-model pro desktop aplikace (WinForms, WPF, MAUI, Uno, Avalonia), UI vlákna a
SynchronizationContext
, který používajíTask.Start
/ContinueWith
a podobné.Task.ConfigureAwait
a příklady IAsyncEnumerable
,IAsyncEnumerator
,await foreach
, asynchronní iterátorové metody a příklady s použitím v síťovém spojeníConsole.Out.WriteLineAsync
Materiály
Doporučená literatura
- Mark Michaelis with Eric Lippert: Essential C# 5.0, Addison-Wesley, 2013 (lze koupit např. na Amazon UK)
- Jeffrey Richter: CLR via C# (4th Edition), Microsoft Press, December 2012 (lze koupit např. na Amazon UK)
- Jon Skeet: C# in Depth (3rd Edition), Manning Publications, September 2013 (lze koupit např. na Amazon UK)
- blog Erica Lipperta (bývalý člen C# týmu v Microsoftu): Fabulous Adventures In Coding
- C# Language Specification 5.0
Případně
- Christian Nagel, Evjen, Jay Glynn, Karli Watson, Morgan Skinner: Professional C# 4.0 and .NET 4, Wrox, John Wiley & Sons, March 2010 (lze koupit např. na Amazon UK
Náplň cvičení
1. Cvičení
- Úvodní cvičení, požadavky na splnění předmětu. Informace o požadavcích na splnění předmětu jsou k dispozici taky na této stránce.
- Uživatelsky definované konverzní operátory
- rozdíly oproti funkci
X ToX()
, fluent syntax - explicitní, implicitní konverze
- Příklad
- rozdíly oproti funkci
- Další uživatelsky definované operátory
- Aritmetické:
+
,-
(unary and binary),*
,/
,%
,++
,--
- Relační:
==
,!=
,<=
,>=
,<
,>
- Bitové:
&
,|
,^
,~
,>>
,<<
- Příklad
- Aritmetické:
- Domácí úkol
- Kostra
- Zařídit, aby se přeložil projekt
GamePhysics
a vypsal očekávaný výstup, bez zásahu do funkceMain
(API zákazníka) - Zařídit, aby se přeložil projekt
JumpingPlatformGame
tak, aby měl očekávané chování, bez zásahu do souboruMainForm.cs
(API zákazníka) - Projekt
JumpingPlatformGame
závisí na projektuGamePhysics
. Stačí tedy upravovat souboryGamePhysics/Program.cs
aJumpingPlatformGame/Entities.cs
2. Cvičení
- Struktury jako interface, boxování, příklad
- Overload generických metod, příklad
- Overload podle interface a boxování, řešení
- Overload podle
where
constraint, nefunkční řešení - Member-hiding v rámci dědičnosti s
where
constraint, nefunkční řešení - Extension metoda s
where
constraint, řešení
- Domácí úkol
- Kostra
- Upravit projekt
MinimalisticUIFramework
, přidáním podpory pro Panely v rámci frameworku na výrobu GUI aplikací, bez změn v API v rámci projektuDemoApp.MinimalisticUIFramework
(Part 1) - Zařídit možnost přidávání
Control
s doPanel
s pomocí fluent-syntax v projektuDemoApp.MinimalisticUIFramework
(Part 2)
3. Cvičení
- Komentáře k DU01
Second
,Meter
,MeterPerSecond
jakostruct
, protože nechceme referenční sémantiku (jedná se o hodnoty)- Benchmark testující rozdíl mezi typem
double
zabaleném vclass
nebostruct
(používá knihovnu BenchmarkDotNet); Příklad
- Benchmark testující rozdíl mezi typem
- Implicitní konverze mezi jednotkami různých typů, případně pro
int
/double
jsou nebezpečné (chceme zachovat silnou typovost) LimitedPositionUpdater
jen jako seskupení rychlosti a lower/upper bound (zobrazovaná část hry), protože znovu referenční sémantika nám nic nepřidá- A dovolí nám to implementovat
UpdatePosisiton
jak pro vertikální tak pro horizontální pohyb
- A dovolí nám to implementovat
- Možné řešení
- Komentáře k DU02
- Implementace panelů v samostatném souboru. Základ
abstract class Panel
a potomciStackPanel
aCanvas
- Možné řešení
- A diskuse o alternativních přístupech (
.GetType().Name
,Panel<T>
aList<T> children
) - Knihovna => dokumentační komentáře
- Implementace panelů v samostatném souboru. Základ
- Nový DU,
ImmutablePeople
, Kostra- Přidat nový soubor s implementací požadovaných tříd tak, aby se
Program.cs
přeložil a vypsal stejný výstup jako je v souboruImmutablePeople.txt
- Jednotlivé instance musí být immutable, modifikace probíhá pomocí metod
With
(fluent syntax) - Bez použití C#9.0
record
- Přidat nový soubor s implementací požadovaných tříd tak, aby se
4. Cvičení
- Prodloužen deadline na DÚ03 do příštího cvičení
- .NET source code browser, oficiální repozitář, dekompilace pomocí ILSpy, nebo z metadat VS pomocí Go to defenition (F12)
- Zadání nového DÚ — Fixed Point:
- Kostra
- Implementace typu
Fixed<TBackingType, TPrecision>
jakožto reálného čísla s pevnou pozicí desetinné čárky - Operace
+-*/
,new(int)
,new(double)
,ToDouble
,Console.WriteLine(Fixed)
,To<TDifferentPrecision>
,List<TNumber>.SumAll
5. Cvičení
- Komentáře k řešení ImmutablePeople
- Je špatně duplikovat
WithName
doStudent
iTeacher
(protože budu mít desítky druhů osob a stovky vlastností co si musím pamatovat => tisíce metod) - Vyrábění instancí pomocí clonování (
abstract Person Clone()
aoverride Teacher Clone()
díky kovarianci) - Mezitřída ConcretePersonBase
, která zná informace o svých potomcích (díky typovému argumentu T
) - Možné řešení
- Je špatně duplikovat
- Komentáře k řešení FixedPoint
- Interface
IDictionary<TKey, TValue>
,IReadOnlyDictionary<TKey, TValue>
a diskuse nad variantnostíTKey
aTValue
- Zadání nového DÚ — Validators
6. Cvičení
- Komentáře k řešení Validators
- Problém s metodou
ValidateSuperOrders(IEnumerable<SuperOrder>, Validator<?>)
aby přijímalaOrderValidator
i nějaký jinýSuperOrderValidator
- interface
IValidator<in T>
kontravariantní podleT
umožní předatOrderValidator
doValidateSuperOrders(IEnumerable<SuperOrder>, Validator<SuperValidator>)
- Co má formálně vracet
Validate
?List<ValidationError>
, moc přísné, když už, tak alespoň obecnýIList
, který je ale mutableIReadOnlyList<ValidationError>
, který ale možná ani nevyužiji, takIEnumerable<ValidationError>
(potenciální použití iterátorových metod)
- Co má skutečně vracet
Validate
?List<ValidationError
,ValidationError[]
,ValidationError[0]
(Array.Empty<T>
),OneEnumerable
,ZeroEnumerable
,null
RangeValidator<T>
pouze omezení naIComparable<T>
Validator
nadIValidator
jako framework na vyrábění složitějších validátorůparams
a problémy (předávání 0 nebo 1 argumentu)AdvancedOrderValidator
pomocí factory metod
- Problém s metodou
- Zadání nového DÚ — Deque 2.1, Deque 2.2 (dva týdny deadline)
- V ReCodExu, ve skupině pro letní semestr
7. Cvičení
- Se nekoná (probíhá deadline na úlohy Deque)
7. Cvičení
- Připomenutí fungování webu (HTTP protokol), fungování distribuovaných webových služeb dle modelu REST a WebAPI, url encode
- Přístup webové službě ze C# pomocí
HttpClient
aGetStringAsync
(bez znalostí konceptůTask
aasync
, jen s využitím.Result
) - Deserializace odpovědi webové služby pomocí
JsonSerializer
aJsonSerializerOptions
do silně typovaných objektů - Využití knihovny Refit pro definici WebAPI pomocí C# interface (silná typovanost)
- Koncept webového serveru z ASP.NET (Kestrel) a použití
- Zadání nového vláknovacícho DÚ — WebAPI (deadline do příštího cvičení)
- Kostra (obsahuje také příklady prezentované na cvičení)
-
- část: Definice potřebných typů pro silně typovaný přístup k WebAPI služby CoinBase (
CoinBaseWebApi
) s využitím knihovny Refit
- část: Definice potřebných typů pro silně typovaný přístup k WebAPI služby CoinBase (
-
- část: Implementace frameworku pro silně typovanou deklaraci WebAPI na straně serveru (
SimplisticWebApiConsoleApp
) s použitím reflection
RequestProcessor.RegisterAllRoutes
pomocí reflection najde všechny implementaceISimplisticRoutesHandler
od kterých vyrobí bezparametrických konstruktorem instanci, na které zavoláRegisterRoutes
ISimplisticRoutesHandler.RegisterRoutes
doRouteMap
přidá mapování cesta (url) -> metoda (request handler) (syntaxe zPostRoutesHandler
)RequestProcessor.HandleRequest
podlepath
najde vRouteMap
správnou funkci, kterou zavolá z parametry, které naparsuje zquery
- část: Implementace frameworku pro silně typovanou deklaraci WebAPI na straně serveru (
8. Cvičení
- Připomenutí fungování LINQ a LINQ to Objects
- Lehký úvod do anonymních typů, další LINQ operátory (
let
,orderby
,ThenBy
,join
,groupby
,SelectMany
) a LINQ to Objects operátory (MSDN) - Zadání nového DÚ — LINQ (deadline do příštího cvičení)
- Kostra (obsahuje také přeložené referenční řešení pro ověření výstupu, které nemáte dekompilovat)
- Třída
Person
popisující osobu aGroup
(IEnumerable<Person>
) jako skupinu osob - Pro každý z Assignment připravit LINQ dotaz nad instancí
Group
, který popisuje podmnožinu osob; následně dotaz vyenumerovat - Spuštění s D1 a D2 poskytuje ladící informace k tomu jak moc se které kolekce enumerují. Výstup Vašeho řešení s D1 nebo D2 by neměl být viditelně horší
9. Cvičení
- Diskuse jestli používat explicitní eager vyhodnocení dotazu (
.ToList
) nebo ne a v jakých scénářích (příklad) - Zopakování použití základního API třídy
Thread
a způsoby jak dovnitř dostat data pro výpočet a z venku se dozvědět o výsledku (příklad) - Nová vláknovací úloha: Merge Sort Query
- Použití surových vláken (
System.Threading.Thread
, nikolivSystem.Threading.Tasks
neboSystem.Threading.ThreadPool
; a neSystem.Linq
) - Kostra řešení (pozor, z technických důvodů je to .NET Framework 4.5 (možné upgradovat na 4.8), ale kostra není podporovaná na .NET Core)
LibraryModel/Model.cs
je model knihovny, která se nahraje- Obsahuje knihy (ISBN, Název, Autor, Polička)
- Polička je od
00A
do99Z
- Knihovna může obsahovat vícero kopií stejné knihy (
Copy
) - Kopie může být vypůjčena (
CopyState
) a má unikátní ID Copy.OnLoad
je popis kdo si kopii vypůjčil a kdy bude vrácena- Klient má jméno a příjmení
- Knihovna jsou seznamy knih, kopií, výpůjček a klientů
MergeSortQuery/MergeSortQuery.cs
obsahuje tříduMergeSortQuery
- Vlastnost
ThreadCount
říká maximální počet vláken, které aplikace můžou použít (včetně už bežícího vlákna) - Vlastnost
Library
obsahuje referenci na instanci modelu - Metoda
ExecuteQuery
by měla vrátit nový seznam setříděných a vyfiltrovaných kopií (více níže)
- Vlastnost
Program.cs
má nastavení náhodného generátoru obsahu knihovny (default 800MB, dá se nastavit 1500MB nebo 5000MB; to vyžaduje assembly přeloženou pro procesory x64)- Také obsahuje
ReferenceTiming*.txt
které obsahuje měření na nějakém stroji. Měření vašeho řešení by mělo vykazovat podobné vlastnosti, konkrétně- Vaše řešení pro
ThreadCount == 1
by nemělo být výrazně pomalejší než referenční sériové řešení - Více vláknové řešení by mělo být viditelně rychlejší než jedno-vláknové
- Ještě více paralelní řešení (až do počtu fyzických jader vašeho procesoru) by mělo vykazovat nějaké netriviální zrychlení
- Řešení pro dvě vlákna nemůže být dvakrát rychlejší než jedno-vláknové řešení (minimálně ne proto, že finální merge nejde dělat paralelně)
- Vaše řešení pro
- Cílem je zařídit dvě věci: filtrování a třídění
- Filtr (Zamyslete se kdy filtrovat, jestli před třídění, během merge nebo po třídění)
OnLoan != null
aShelf
mezixxA
andxxQ
- Třídění
- podle
Loan.DueDate
; pak podleClient.LastName
; pak podleClient.FirstName
; pak podleBook.Shelf
; pak podleCopy.Id
- podle
- Vaše řešení vyrábí soubory
ResultMergesort*Threads.txt
aResultReference*.txt
, které obsahují výsledek (tedy vyfiltrované a setříděné kopie). Vaše řešení musí mít správný výstup. Zkontrolujte si tedy Váš výstup s referenčním, třeba pomocídiff
nebo nějakého checksum algoritmu (např.md5
)
- Použití surových vláken (
10. Cvičení
- Komentáře k úloze Merge Sort Query
- Přirozený přístup vede na kód kde nemusím znovu vyrábět vlákna
- Stejně tak se dá rozdělit na kterých datech jednotlivá vlákna pracují a zámky nejsou třeba
- Prezentace o problémech s atomičností (atomicity violations) a jednoduchém zamykání
- Nová vláknovací úloha: Antisocial Robots
- Skeleton (stejné jako výše)
Robot.cs
máLocation
, což jsou souřadnice jeho pozice v herní plošeRobotSimulationBase.cs
má_roomCells
, což je herní plocha s referencemi na robotyRobotSimulation.cs
je soubor, který pracuje se dvěma důležitými funkcemi:SimulateOneStep
která provede jeden krok simulace robota s použitím následující metodyDetermineNewLocation
pro získání souřadnic políčka, kam by se měl robot pohnout
- Vaším úkolem je opravit tyto dvě metody tak, že nebudou obsahovat žádné atomicity violations; tedy zajistit, že každé použití proměnných je buď isolated, immutable nebo synchronized (pojmy z prezentace)
- Očekává se použití základních zámků ve formě
lock(obj) { ... }
, tak- že to funguje (tedy nebudou nastávat atomicity violations)
- že to je efektivní (tedy řešení jedním zámkem přes celou metodu není správné)
- že se nebudou vyskytovat deadlocks
- Pozor, že vaše řešení si nemůžete otestovat. To, že vaše řešení nějak seběhne ještě neznamená, že by tomu tak bylo vždycky, vzhledem k tomu, že je paralelismus nedeterministický
- Neměňte strukturu kódu (tedy zachovejte existenci metod
SimulateOneStep
aDetermineNewLocation
), pouze opravte problémy související s více-vláknovým programováním - Můžete přidávat nové vlastnosti/proměnné (např. na jako zámky)
- Odevzdejte pouze
RobotSimulation.cs
11. Cvičení
- Drobné komentáře k AntisocialRobots (více viz video), Možné způsoby řešení
- úprava frameworku, místo počítání pozic => špatné řešení
- použití něčeho co dědí od
WaitHandle
=> špatné řešení - zamykání v nějaké metodě a párové odemykání v jiné metodě => těžké na rozmyšlení a nekonzistentní
- globální zámek / dlouhé kritické sekce => extrémní zpomalení
lock(x){}
vs.Monitor.Enter(x)
aMonitor.Exit(x)
a problémy s výjimkami- Diskuse nad možnými data-races u předchozích příkladů z přednášek a cvičení
- Další příklad na asynchronní metody,
async
,await
,SemaphoreSlim
, - Nová vláknovací úloha:
AsyncSemaphore
(deadline 4.6.2023 23:59), zadání vizte separátní video (odkaz v mailu) - Připomenutí pravidel pro zápočet a bonusové body ke zkoušce
- Nová vláknovací úloha:
AhoCorasick
(deadline 11.6.2023 23:59), zadání vizte separátní video (odkaz v mailu)
Informace o zkoušce
Zkouška probíhá primárně písemnou formou, a v každé zkouškové písemce je kolem 6 až 8 otázek (některé obsahují podotázky). U každé otázky, případně podotázky, je dole uvedeno, jaký maximální počet bodů (=N
) lze za správně odpovězenou otázku/podotázku získat: N
bodů získáte v případě, že je odpověď na otázku správně; 0,5 * N
bodu získáte, pokud odpověď není zcela kompletní, ale jinak je správná (tj. nějaká malá část odpovědi chybí nebo je nepřesná); v ostatních případech získáte 0
bodů (tj. pokud v odpovědi chybí větší část, nebo je odpověď na otázku plně nebo i jen z části nesprávná).
Celkem lze z každé písemky získat maximálně 10
bodů. Mapování získaných bodů na výslednou známku je následující:
Body z písemky | Výsledná známka |
---|---|
10 – 8,5 | 1 |
8 – 6,5 | 2 |
6 – 5 | 3 |
4.5 – 0 | 4 |
Každá zkoušková písemka trvá 150 minut, tj. ideálně 20 minut na každou otázku + 30 minut bezpečnostní rezerva. Po písemné části následuje ústní část, kde zkoušející se studentem prochází jeho písemku, a případně nepřesností/nejasností u některých odpovědí se ptá na doplňující otázky — na základě toho je určeno finální bodové hodnocení každé otázky. Základem hodnocení je ale vždy písemná část, tedy u otázky bez odpovědi nebo se špatnou odpovědí nelze ani po ústní části získat více než 0 bodů.
Níže budou pro ilustraci uvedena zadání vybraných písemek z již proběhlých termínů:
Doplňkové informace o zkoušce
Kromě informací uvedených ve slidech z první přednášky navíc pro zkoušky z NPRG035, NPRG038, a NPRG057 platí následující 2 body:
- Pokud někdo bude zapsán na nějakém z termínů zkoušky a na termín se nedostaví, bude mu tento termín v SISu označen jako propadlý (tj. student přijde o jeden pokus). Cílem tohoto opatření je optimalizace vytíženosti jednotlivých termínů, aby všichni studenti měli možnost přijít až na 3 termíny zkoušky.
- Pokud někdo na zkoušce získá známku 2 nebo 3 a bude si chtít svůj výsledek zlepšit, může explicitně na místě během vyhodnocení zkouškové písemky požádat zkoušejícího o nezapsání známky. Zkušební termín mu pak bude v SISu označen jako propadlý. Takový student může pak později
- požádat o dodatečné zapsání získané známky, nebo
- přijít na jiný termín zkoušky (jakýmkoliv výsledkem této “opravné” zkoušky se ovšem anuluje předchozí získaná známka).
Modelový příklad 1:
Student X získá na 1. termínu známku 2 a odmítne ji. Na 2. termínu získá známku 3 a odmítne ji. Na 3. termínu získá známku 1.
Aktuální stav studenta X: 1. termín = propadlý, 2. termín = propadlý, 3. termín = 1, tj. student X zkoušku splnil s hodnocením 1.
Modelový příklad 2:
Student Y získá na 1. termínu známku 3 a odmítne ji. Na 2. termínu získá známku 4.
Aktuální stav studenta Y: 1. termín = propadlý, 2. termín = 4, tj. pokud chce zkoušku splnit, musí student Y přijít na 3. termín. Pokud na 3. termínu opět získá známku 4, tak zkoušku nesplnil.
Modelový příklad 3:
Student Z se nedostaví na 1. termín, na 2. termínu získá známku 3 a odmítne ji, na 3. termínu získá známku 4.
Aktuální stav studenta Z: 1. termín = propadlý, 2. termín = propadlý, 3. termín = 4, tj. student Z zkoušku nesplnil.
Informace o zápočtu
Pro získání zápočtu je nutné dvě podmínky:
1. Domácí úkoly
Během semestru bude zadáno několik (10-12) domácích úkolů. Náročnost těchto úkolů se může různit. Za správné vypracování úkolu dostane student značku OK
. Pokud se v řešení vyskytnou nějaké problémy (např. chybějící implementace nějaké malé části úkolu), dostane student značku OK-
. Naopak, pokud bude řešení velmi kvalitní nebo jinak nadstandardní, dostane student značku OK+
. Kladné značky umí odmazávat mínuska u negativních značek. Pro splnění této podmínky je nutné získat alespoň 5 značek OK
, z nichž alespoň 2 jsou na téma více-vláknového programování; nebo alespoň 1 na více-vláknové programování a alespoň 1 na dobrovolné pokročilé (extended track) koncepty. Domácí úkoly se hodnotí individuálně. Pokud si nejste celkovým hodnocením jistí (např. máte nemálo značek OK-
), zeptejte se svého cvičícího.
Každá další značka OK
nad 5 přidává +0.25 bodů ke zkoušce
Domácí úkoly nemají formální specifikaci. Je na zodpovědnosti studenta správně úkolu porozumět ptaním se otázek během cvičení. Domácí úkoly se odevzdávají prostřednictvím modulu Studijní mezivýsledky v SISu. Je nutné nahrávat celá řešení jako archív ZIP (samotné .cs
soubory nemusí v některých případech stačit, např. pokud zadání vyžaduje připravení NuGetích balíčků). Na rozdíl od systému ReCodEx nebude studentům k dispozici okamžitý feedback k nahranému řešení, nýbrž bude třeba vyčkat na ohodnocení cvičícím.
Upozornění: Domácí úkoly jsou samostatnou prací, jejímž cílem je zhodnotit schopnost studenta samostatně vypracovat složitější program v jazyce C#. Pokud bude zjištěno, že některý student odevzdal cizí řešení (např. několik studentů odevzdalo různé instance stejného řešení některého domácího úkolu, apod.), bude to považováno za pokus o podvod. Všichni takoví studenti nesplní předmět NPRG038 v tomto akademickém roce a přicházejí o možnost uznání splněných povinností v roce příštím; případně bude disciplinární komisi UK MFF doporučeno jejich vyloučení ze studia!
2. Zápočtový program
Termíny:
- Specifikace: 7. 7. 2023
- Předvedení finální plně funkční verze (včetně uživatelské a programátorské dokumentace):
-
- deadline: 9. 8. 2023
-
- deadline: 8. 9. 2023
-
Jeden zápočtový program může být použit pro splnění povinností z vícero předmětů o C#, pokud je program dostatečně rozsáhlý.
- Požadavky pro NPRG035 + NPRG038:
- Předvedeno do 1. deadline: minimálně 45 kB zdrojového kódu v jazyce C#
- Předvedeno do 2. deadline: minimálně 60 kB zdrojového kódu v jazyce C#
- Předvedeno po 2. deadline: minimálně 90 kB zdrojového kódu v jazyce C#
Zdrojové kódy musí být ručně psané (nevygenerované) a rozumné, včetně rozumných komentářů.
Zápočtový program vyžaduje rozumné a netriviální použití technologií probíraných na přednáškách a cvičeních (jako např. více-vláknové programování, síťování, LINQ, Reflection, …).
Osobní předvedení je součástí odevzdání. Na předvádění si připravte několik slides shrnujících hlavní funkce programu, hlavní řešené problémy a nástin architektury.
Uznávání povinností z minulých let
Pokud jste tento předmět měli zapsaný loňský akademický rok a splnili jste pouze některé z povinností potřebných pro udělení zápočtu, může vám je po explicitním požádání (např. při předvádění zápočtového programu) uznat váš letošní cvičící (lze uznat splněnou docházku, domácí úkoly, zápočtový test, odevzdaný a schválený zápočtový program). Téma zápočtového programu (pokud ho ještě nemáte dokončený) nemusí být novým cvičícím uznáno. Pokud jste v loňském roce úspěšně složili zkoušku, ale nepodařilo se vám získat zápočet, opět po explicitním požádání vám může zkoušku uznat Pavel Ježek. Toto je iniciativa vyučujících tohoto předmětu a nelze ji požadovat po studijním oddělení!