BSY
Topics
Security analysis of operating systems, development of secure software and web applications security. Analysis of cyberattacks and malware. Security of mobile devices. BE4M36BSY (Course web pages)
Questions
- Managing a software project with a security as an objective, advantages and disadvantages of waterfall and ellipse model for this use-case, systematic identification of potential vulnerabilities, STRIDE, attack modelling (attack trees), ranking of vulnerabilities (ideal, DREAD).
- Timing and storage covert channels, Side channel attacks, Steganography.
- Discretionary access control(Access control list, Capabilities), Mandatory access control, Multi-level security, Biba model, Multi-lateral security, Role-based access control.
- Privilege escalation, security of operating systems, trusted computer base, reference monitor, complete mediation, needed mechanism for securing current OS, memory management, rings.
- Virtualization, virtual machine monitor, micro-kernels, general-purpose sandboxing, danger, Kernel namespaces, seccomp, Linux kernel capabilities.
- Access control model of web ecosystem, single-origin policy, preservations of integrity of data and code, sandboxing in web, content security policy.
- Network protocols, TCP, DNS, BGP, security of HTTPs, mechanism of certificates, security of certificate infrastructure.
- Firewalls, network intrusion detection, network intrusion prevention, thin client, intrusion deflection.
- Denial of service attack, reflection attacks, syn-cookies, detection and protection against DOS.
Bezpečnostní řízení projektů softwaru
Bezpečnost je klíčovou součástí každého softwarového projektu. Správné řízení projektu s důrazem na bezpečnost může pomoci snížit rizika a minimalizovat náklady na opravy bezpečnostních nedostatků v pozdějších fázích projektu.
Existují různé modely řízení projektů softwaru, ale v této souvislosti se zaměříme na Waterfall a Elipsa model.
Waterfall model
Waterfall model je lineární proces řízení projektů, který se skládá z jednotlivých fází, které se následují:
- Definice požadavků: V této fázi jsou stanoveny všechny požadavky na projekt.
- Návrh: V této fázi se navrhuje architektura projektu a připravuje se plán realizace.
- Implementace: Tato fáze zahrnuje samotnou implementaci projektu.
- Testování: V této fázi se testují jednotlivé části projektu a ověřuje se, zda splňují stanovené požadavky.
- Dodávka: V této fázi se projekt dokončuje a dodává se zákazníkovi.
Výhodou Waterfall modelu je jeho jednoduchost a přehlednost, která usnadňuje řízení projektu. Nevýhodou je však jeho nedostatečná flexibilita, což může být problematické v případě, že se objeví nějaké neočekávané problémy během realizace projektu.
Elipsa model
Elipsa model je iterativní proces řízení projektů, který se skládá z opakujících se fází:
- Plánování: V této fázi se stanovují cíle a požadavky na projekt.
- Návrh: V této fázi se navrhuje architektura projektu.
- Implementace: Tato fáze zahrnuje samotnou implementaci projektu.
- Testování: V této fázi se testují jednotlivé části projektu a ověřuje se, zda splňují stanovené požadavky.
- Hodnocení: V této fázi se hodnotí výsledky projektu a plánuje se další iterace.
Výhodou Elipsa modelu je jeho flexibilita, což umožňuje rychlé reakce na změny v průběhu projektu. Nevýhodou může být větší náročnost na řízení projektu, jelikož každá iter
Systematic identification of potential vulnerabilities
Systémová identifikace potenciálních zranitelností
- Systémová identifikace potenciálních zranitelností je důležitým krokem pro zajištění bezpečnosti systému.
- Proces zahrnuje systematickou analýzu všech aspektů systému.
- Identifikuje se potenciální zranitelnosti, posuzuje se jejich pravděpodobnost a potenciální dopad a stanovuje se jejich prioritizace pro odstranění.
- Existují různé metody, jako je manuální analýza, automatické skenování a penetrační testování, které mohou být použity samostatně nebo v kombinaci pro poskytnutí komplexního hodnocení zranitelností systému.
- Manuální analýza zahrnuje důkladný přezkum architektury, návrhu a implementace systému zkušenými bezpečnostními odborníky.
- Automatické skenování identifikuje známé zranitelnosti v systému rychleji, ale vyžaduje manuální ověření a posouzení, zda jsou zranitelnosti skutečné.
- Penetrační testování simuluje útok na systém, aby se zjistilo, zda existují skryté zranitelnosti.
- Identifikace potenciálních zranitelností chrání citlivé informace před útoky a pomáhá minimalizovat rizika.
STRIDE
STRIDE je zkratka pro sedm nejčastějších hrozeb v
kybernetické bezpečnosti:
- Spoofing (falešné identifikace) - útočník se vydává za jiného uživatele nebo za systém
- Tampering (pozměňování) - útočník mění data nebo kód v systému
- Repudiation (popírání) - útočník popírá svou účast v útoku nebo transakci
- Information disclosure (odhalení informací) - útočník získává nebo odhaluje citlivé informace
- Denial of Service (odmítnutí služby) - útočník přetíží systém nebo službu, aby byla nedostupná pro ostatní uživatele
- Elevation of privilege (zvýšení oprávnění) - útočník získává vyšší oprávnění, než které mu bylo původně přiděleno
- Authorization bypass (obcházení autorizace) - útočník se dostává do systému bez nutnosti platného ověření identity nebo oprávnění
Použití této metodiky může pomoci při analýze bezpečnostních hrozeb a návrhu ochranných opatření.
Attack modelling (attack trees)
Útokové modelování (stromy útoků) je metoda, která se používá k identifikaci možných zranitelností v systému a kategorizaci útoků, které by mohly být na systém provedeny. Tato metoda umožňuje analyzovat potenciální hrozby a navrhnout zabezpečení systému proti nim.
Attack trees jsou grafické nástroje, které reprezentují útoky na systém pomocí stromové struktury. Kořen stromu představuje cíl útoku, zatímco listy stromu představují konkrétní způsoby, jak útok na cíl dosáhnout. Každý uzel stromu reprezentuje jednu zranitelnost nebo krok v útoku.
Použití attack trees umožňuje identifikovat nejpravděpodobnější útoky a navrhnout opatření pro zvýšení bezpečnosti systému. Tato metoda také umožňuje určit, které zabezpečovací opatření jsou nejúčinnější a které jsou méně účinné.
Attack modelling (attack trees) jsou užitečným nástrojem pro každého, kdo se zabývá kybernetickou bezpečností. Tato metoda umožňuje identifikovat a analyzovat potenciální hrozby a navrhnout opatření pro ochranu systému proti nim.
Ranking of vulnerabilities (ideal, DREAD)
Ideální
Ideální ranking zranitelností se skládá z pěti kritérií:
- Vliv (Impact) - jak moc by zranitelnost mohla poškodit organizaci
- Pravděpodobnost (Likelihood) - jak pravděpodobné je, že se zranitelnost vyskytne
- Využitelnost (Ease of Exploitation) - jak snadné je zranitelnost využít
- Zjištění (Discoverability) - jak snadné je zranitelnost najít
- Důležitost (Importance) - jak důležitá je pro organizaci ohrožená oblast
DREAD
DREAD ranking zranitelností se skládá z pěti kritérií:
- Vliv (Damage) - jak moc by zranitelnost mohla poškodit organizaci
- Reprodukovatelnost (Reproducibility) - jak snadné je zranitelnost reprodukovat
- Exploitabilita (Exploitability) - jak snadné je zranitelnost využít
- Postižení uživatelů (Affected Users) - kolik uživatelů by mohlo být zasaženo zranitelností
- Rozšíření (Discoverability) - jak snadné je zranitelnost najít
Timing and storage covert channels
Časování a ukládání skrytých kanálů
Popis
Skryté kanály jsou metody, které umožňují komunikaci mezi útočníkem a obětí bez detekce ze strany bezpečnostních opatření. Časování a ukládání skrytých kanálů jsou dva způsoby, jak mohou být skryté kanály implementovány.
Časování skrytých kanálů: Tento typ skrytého kanálu využívá různých časových prodlev mezi různými akcemi, jako jsou například požadavky na server nebo odesílání dat. Tyto prodlevy jsou použity jako kódování pro přenos informací.
Ukládání skrytých kanálů: Tento typ skrytého kanálu využívá různých možností ukládání dat, jako jsou například metadata souborů nebo skryté sektory na pevném disku. Tyto metody jsou použity k ukládání informací, které jsou později získány útočníkem.
Příklad využití
Útočník může využít časování skrytého kanálu k přenosu informací mezi svým počítačem a obětí. Například může použít prodlevu mezi požadavky na server k přenosu informací v kódované formě.
Další možností je využití ukládání skrytého kanálu k ukládání informací na pevný disk oběti. Útočník může využít skrytých sektorů na disku k ukládání informací, které jsou později získány pomocí speciálního softwaru.
Prevence
Prevence skrytých kanálů zahrnuje monitorování časových prodlev a ukládání dat na počítači. Bezpečnostní opatření by měla být navržena tak, aby minimalizovala možnosti využití skrytých kanálů útočníky. Například by měla být omezena možnost ukládání dat na pevný disk a monitorovány časové prodlevy.
Side channel attacks
Side channel attacks are a type of cyber attack that exploits weaknesses in a system’s physical or electromagnetic characteristics, such as power consumption, electromagnetic radiation, or sound, to extract sensitive information. These attacks are often used to bypass encryption or other security measures and can be difficult to detect.
Types of Side Channel Attacks
Power Analysis Attack: This attack involves analyzing the power consumption of a device to determine the secret key used in encryption.
Electromagnetic Attack: This attack involves analyzing the electromagnetic radiation emitted by a device to determine the secret key used in encryption.
Acoustic Attack: This attack involves analyzing the sound produced by a device to determine the secret key used in encryption.
Prevention of Side Channel Attacks
Implementing Countermeasures: Implementing countermeasures such as noise reduction techniques, shielding, and filtering can help prevent side channel attacks.
Using Advanced Encryption: Using advanced encryption algorithms that are resistant to side channel attacks can also help prevent these attacks.
Regular Security Audits: Regular security audits can help identify and address any vulnerabilities that may be exploited by side channel attacks.
Steganography
Steganografie je technika skrytí dat uvnitř jiných dat, aby se skryla existence samotného zprávy. Tato technika se často používá k ukrývání škodlivého kódu nebo citlivých informací. Steganografie může být detekována pomocí specializovaných nástrojů, které jsou navrženy k odhalení skrytých dat. Je důležité mít vědomosti o této technice, aby se zabránilo útokům, které využívají steganografii.
Discretionary access control(Access control list, Capabilities)
Discretionary access control (DAC) - řízení přístupu na základě diskrece uživatele
Co to je? DAC je typ řízení přístupu, který umožňuje uživatelům kontrolovat přístup k objektům, jako jsou soubory a složky, na základě své diskrece. To znamená, že uživatelé mohou rozhodnout, kteří další uživatelé nebo skupiny mají přístup k jejich objektům.
Jak to funguje? DAC využívá dvou metod řízení přístupu: Access control list (ACL) a Capabilities. ACL umožňuje uživatelům určit, kdo má přístup k jejich objektům a jaký typ přístupu mají. Capabilities na druhé straně umožňují uživatelům určit, ke kterým objektům mají ostatní uživatelé přístup a jaký typ přístupu mají.
Proč je to důležité v kybernetické bezpečnosti? DAC je důležitým nástrojem v kybernetické bezpečnosti, protože umožňuje uživatelům kontrolovat přístup k důležitým datům a informacím. Pokud jsou tyto objekty špatně chráněny, mohou být snadno ohroženy útokem hackerů. DAC umožňuje uživatelům chránit své objekty a informace před neoprávněným přístupem.
Poznámka: V českém jazyce se používá termín řízení přístupu na základě diskrece uživatele pro Discretionary access control.
Mandatory access control
Mandatory Access Control (MAC) je bezpečnostní mechanismus v kybernetické bezpečnosti, který řídí přístup k datům a zdrojům na základě předem definovaných pravidel. Tyto pravidla jsou vytvořeny administrátorem systému a aplikovány na uživatele a procesy.
MAC je účinným způsobem, jak minimalizovat rizika způsobená útoky na systém. Umožňuje správci systému přesně definovat, kdo má přístup k určitým datům a zdrojům a co s nimi může dělat. Tím se snižuje riziko, že neoprávněný uživatel získá přístup k citlivým informacím nebo je poškodí.
MAC je často používán v prostředí s vysokou úrovní bezpečnosti, jako jsou vládní organizace, finanční instituce a průmyslové podniky. Je to důležitý nástroj v boji proti kybernetickým hrozbám a je nezbytný pro ochranu citlivých dat a informací.
Povinná kontrola přístupu (MAC) je bezpečnostní mechanismus, který řídí přístup k datům a zdrojům na základě předem definovaných pravidel. Tento mechanismus minimalizuje riziko útoků na systém a snižuje riziko získání přístupu k citlivým informacím nebo jejich poškození. MAC je často používán v prostředí s vysokou úrovní bezpečnosti, jako jsou vládní organizace, finanční instituce a průmyslové podniky.
Multi-level security
Multi-level security (MLS) je koncept zabezpečení, který se používá v oblasti kybernetické bezpečnosti. Tento koncept zahrnuje použití různých úrovní zabezpečení pro různé části systému. Každá úroveň zabezpečení má své vlastní pravidla a omezení, které pomáhají chránit systém před útoky.
MLS se používá v mnoha různých oblastech, včetně vládních a vojenských systémů, finančních institucí a podobně. Většina systémů MLS používá tři nebo více úrovní zabezpečení, ale některé mohou mít i více než deset úrovní.
Každá úroveň zabezpečení má své vlastní názvy a čísla, například Top Secret (nejvyšší tajné), Secret (tajné), Confidential (důvěrné) a Unclassified (neutajené). Každá úroveň má také své vlastní pravidla pro přístup a zpracování informací.
Použití MLS může pomoci minimalizovat riziko útoku na systém a chránit citlivé informace. Nicméně, implementace MLS může být nákladná a složitá, a může vyžadovat specializované znalosti a technologie.
Biba model
Biba model je bezpečnostní model, který se používá k ochraně informací a dat. Tento model se zaměřuje na zachování integrity dat a předcházení neautorizovanému přístupu k nim.
Model je pojmenován po svém tvůrci, americkém matematikovi Kennethu Bibovi. Biba model se skládá ze tří základních úrovní:
Integrita dat - Tato úroveň se zaměřuje na zachování integrity dat a zabraňuje jakémukoli neoprávněnému zásahu do dat. Zabezpečuje se tak, aby data nebyla poškozena, ztracena nebo změněna.
Dostupnost dat - Tato úroveň se zaměřuje na zajištění dostupnosti dat pro autorizované uživatele. Zabezpečuje se tak, aby data byla k dispozici v době, kdy jsou potřebná.
Důvěrnost dat - Tato úroveň se zaměřuje na zajištění důvěrnosti dat a zabraňuje neoprávněnému přístupu k nim. Zabezpečuje se tak, aby data byla přístupná pouze autorizovaným uživatelům.
Biba model je velmi užitečný pro organizace, které se zabývají citlivými informacemi a daty. Tento model pomáhá chránit informace a data před útoky a zabezpečuje, že jsou k dispozici pouze pro autorizované osoby.
Multi-lateral security
Multi-laterální bezpečnost znamená spolupráci a koordinaci mezi více stranami v oblasti kybernetické bezpečnosti. To zahrnuje vládní organizace, soukromé společnosti, akademické instituce a další subjekty. Cílem multi-laterální bezpečnosti je zlepšit ochranu proti kybernetickým hrozbám a zvýšit schopnost reagovat na ně.
V rámci multi-laterální bezpečnosti se mohou provádět různé aktivity, jako jsou společné cvičení, výměna informací o hrozbách a zranitelnostech, spolupráce na vývoji bezpečnostních technologií a standardů a další. Tato spolupráce může být regionální, mezinárodní nebo dokonce globální.
V České republice se multi-laterální bezpečnost v kybernetické bezpečnosti provádí prostřednictvím různých iniciativ a organizací, jako jsou Národní centrum kybernetické bezpečnosti, Česká asociace pro kybernetickou bezpečnost a další. Tyto organizace spolupracují s různými subjekty, včetně vládních úřadů, soukromých společností a akademických institucí, aby zlepšily kybernetickou bezpečnost v České republice.
Role-based access control
Role-based access control (RBAC) je metoda řízení přístupu k informacím a systémům založená na přidělování oprávnění uživatelům na základě jejich rolí v organizaci. Tento systém umožňuje správci přidělit uživatelům práva k určitým činnostem na základě jejich pracovních funkcí a odpovědností, což snižuje riziko zneužití oprávnění. RBAC je důležitým prvkem kybernetické bezpečnosti, protože pomáhá minimalizovat riziko útoků ze strany interních a externích hrozeb a zajišťuje ochranu citlivých informací.
Privilege escalation
Privilege escalation představuje zvýšení úrovně oprávnění uživatele v systému. To znamená, že uživatel, který nemá původně dostatečné oprávnění, získává vyšší úroveň oprávnění, aby mohl provádět určité akce, ke kterým by jinak neměl přístup.
Tento proces může být zneužitý útočníky, kteří se snaží získat neoprávněný přístup k systému. Pokud útočník dokáže získat omezené oprávnění, může použít různé techniky, aby získal vyšší úroveň oprávnění a získal tak plný přístup k systému.
Existuje několik způsobů, jak útočníci mohou provést privilege escalation, včetně zneužití chyb v softwaru, zneužití chyb v konfiguraci systému a využití slabých hesel.
Proti privilege escalation útokům mohou být použity různé bezpečnostní opatření, jako jsou aktualizace softwaru, konfigurační změny a zlepšení správy hesel.
Security of operating systems
Bezpečnost operačních systémů je klíčovou součástí kybernetické bezpečnosti. Operační systémy jsou základem pro všechny aplikace a procesy běžící na počítači, a proto je důležité zajistit jejich bezpečnost. Některé z důležitých opatření pro zajištění bezpečnosti operačních systémů jsou:
1. Aktualizace
Aktualizace operačního systému jsou důležité, protože obsahují opravy chyb a zranitelností. Je důležité pravidelně aktualizovat operační systém a všechny nainstalované aplikace, aby se minimalizovala rizika útoku.
2. Antivirový software
Antivirový software je důležitým nástrojem pro ochranu operačního systému. Antivirový software dokáže odhalit a zablokovat škodlivý software, který by mohl poškodit operační systém.
3. Firewall
Firewall je dalším důležitým nástrojem pro zajištění bezpečnosti operačního systému. Firewall dokáže blokovat nežádoucí přístup k počítači a chránit ho před útoky z internetu.
4. Silné heslo
Silné heslo je důležité pro ochranu operačního systému. Heslo by mělo být dostatečně dlouhé a obsahovat kombinaci písmen, číslic a speciálních znaků.
Bezpečnost operačních systémů je důležitá pro ochranu počítače a dat před útoky. Pravidelná aktualizace, antivirový software, firewall a silné heslo jsou důležitými nástroji pro zajištění bezpečnosti operačního systému.
Trusted computer base
Trusted computer base je termín používaný v kybernetické bezpečnosti pro označení části systému, která je považována za důvěryhodnou a zabezpečenou. Tato část systému je obvykle oddělena od zbytku systému a obsahuje kritické funkce, jako jsou autentizace uživatelů, řízení přístupu a záznamy o událostech. Cílem trusted computer base je minimalizovat rizika spojená s útoky na systém a zajistit, aby důvěryhodné informace zůstaly v bezpečí.
Reference monitor
Reference Monitor (Referenční monitor) je základním bezpečnostním mechanismem v oblasti kybernetické bezpečnosti. Je to softwarový mechanismus, který řídí přístup k systému a zajišťuje, že pouze oprávněné osoby mají přístup k citlivým datům a aplikacím.
Referenční monitor funguje jako středník mezi uživateli a systémem. Každý požadavek na přístup k systému musí projít referenčním monitorem, který vyhodnotí, zda je uživatel oprávněn přistupovat k daným datům a aplikacím. Pokud je uživatel oprávněn, referenční monitor povolí přístup. Pokud ne, přístup je zamítnut.
Referenční monitor je klíčovým prvkem v rámci bezpečnostní architektury a je používán v mnoha systémech, včetně operačních systémů, firewalů a antivirových programů. Jeho účelem je minimalizovat rizika spojená s neoprávněným přístupem k citlivým datům a aplikacím a chránit tak uživatele a organizace před kybernetickými hrozbami.
Complete mediation, needed mechanism for securing current OS, memory management, rings.
Kompletní mediací je mechanismus, který zajišťuje, že každá interakce mezi subjekty v systému je řízena a kontrolována. Tento mechanismus zahrnuje kontrolu přístupu, autentizaci, autorizaci a auditování.
Mechanismus pro zabezpečení současného operačního systému
Pro zabezpečení současného operačního systému je třeba použít několik mechanismů, jako jsou firewally, antivirové programy, aktualizace operačního systému a aplikací, zabezpečené připojení k internetu a další.
Správa paměti
Správa paměti je proces, který zajišťuje, že každý proces v systému má přístup pouze k paměti, kterou mu byla přidělena. Tento mechanismus zahrnuje virtualizaci paměti, oddělení procesů a kontrolu přístupu k paměti.
Kruhy
Kruhy jsou mechanismem pro oddělení procesů v systému. Existují čtyři kruhy, přičemž každý kruh má svou úroveň oprávnění. Kruh 0 je nejvyšší úroveň a používá se pro jádro operačního systému. Kruhy 1 a 2 jsou určeny pro ovladače a systémové služby. Kruh 3 je určen pro uživatelské procesy. Tento mechanismus zajišťuje, že procesy v nižších kruzích nemohou ovlivnit procesy v kruzích vyšších.
Virtualization
Virtualizace je proces vytváření virtuálních verzí hardwaru, softwaru nebo síťových prostředků. Tento proces umožňuje oddělit jednotlivé části systému od sebe a simulovat jejich chování. To může být užitečné v oblasti kybernetické bezpečnosti, protože umožňuje izolovat potenciálně nebezpečné aplikace nebo procesy od zbytku systému.
Existují různé typy virtualizace, včetně virtualizace operačního systému, virtualizace aplikace a virtualizace síťových prostředků. Každý typ má své vlastní výhody a nevýhody, a také různé použití v oblasti kybernetické bezpečnosti.
Virtualizace může být použita k izolaci potenciálně nebezpečných aplikací od zbytku systému, což může pomoci chránit systém před útoky malware. Také umožňuje vytvoření testovacího prostředí, ve kterém je možné testovat nové aplikace nebo aktualizace bez rizika poškození systému.
Nicméně, virtualizace také přináší svá vlastní rizika. Pokud není řádně zabezpečena, může být virtuální prostředí cílem útoků. Také může být použita k útoku na jiné systémy, pokud je virtuální prostředí propojeno s jinými sítěmi.
Proto je důležité, aby byla virtualizace správně konfigurována a zabezpečena. To zahrnuje použití silných hesel a šifrování dat v rámci virtuálního prostředí. Také je důležité pravidelně aktualizovat virtuální prostředí a provádět pravidelné kontroly zabezpečení.
Virtual machine monitor
Virtual Machine Monitor (VMM) nebo také hypervisor je softwarová vrstva, která umožňuje běh více virtuálních strojů na jednom fyzickém počítači. VMM zajišťuje izolaci mezi jednotlivými virtuálními stroji a hostitelským operačním systémem, což zvyšuje bezpečnost celého systému. Využití VMM je často doporučováno v oblasti kybernetické bezpečnosti, protože umožňuje izolovat potenciálně nebezpečné aplikace a procesy na jednom virtuálním stroji, což minimalizuje riziko šíření škodlivého kódu na ostatní části systému.
V českém jazyce se Virtual Machine Monitor často označuje jako hypervisor.
Micro-kernels
V oblasti kybernetické bezpečnosti se termín micro-kernels používá pro označení jádra operačního systému, které obsahuje pouze nezbytně nutné funkce a služby. Tento přístup přináší výhody v oblasti bezpečnosti, neboť útočník má méně možností, jak zneužít zranitelnosti v jádře systému.
Kromě toho mohou být funkce operačního systému, které nejsou nezbytné pro běh aplikací, implementovány jako samostatné procesy, které běží mimo jádro. Tím se zvyšuje bezpečnost systému, neboť chyby v těchto procesech nemají vliv na stabilitu jádra.
Celkově lze říci, že použití micro-kernels je jedním z přístupů, jak zvýšit bezpečnost operačního systému a minimalizovat riziko útoků.
General-purpose sandboxing,
Obecné sandboxování je metoda, která slouží k izolaci a omezení přístupu k určitým funkcím a zdrojům aplikace. Tato technologie umožňuje chránit systém před nebezpečným kódem a zabezpečit citlivá data. Sandboxování se používá v různých oblastech, jako je například virtualizace, testování aplikací nebo v oblasti kybernetické bezpečnosti. V oblasti kybernetické bezpečnosti se sandboxování používá k analýze neznámých souborů a programů, které mohou obsahovat malware. Sandboxování umožňuje analyzovat chování programu v izolovaném prostředí, což umožňuje identifikovat nebezpečné chování a přijmout potřebná opatření k ochraně systému.
Kernel namespaces, seccomp, Linux kernel capabilities
Kernelové jmenné prostory
Kernelové jmenné prostory jsou mechanismus, který umožňuje oddělit procesy a zdroje v operačním systému. Tento mechanismus může být využit pro izolaci procesů a snížení rizika útoků v kybernetickém prostředí.
Seccomp
Seccomp je bezpečnostní mechanismus v operačním systému, který umožňuje omezit přístup procesů k systémovým voláním. Tento mechanismus může být využit pro snížení rizika útoků v kybernetickém prostředí.
Linuxové jádrové schopnosti
Linuxové jádrové schopnosti jsou mechanismus, který umožňuje procesům získávat přístup k určitým zdrojům v operačním systému. Tyto schopnosti mohou být využity pro izolaci procesů a snížení rizika útoků v kybernetickém prostředí.
Access control model of web ecosystem
Model přístupové kontroly ekosystému webu se používá k řízení přístupu k informacím a zdrojům na internetu. Tento model zahrnuje různé metody, jako jsou autentizace, autorizace a auditování, které pomáhají chránit citlivé informace a zdroje před neoprávněným přístupem.
Autentizace je proces ověřování identity uživatele. To může zahrnovat použití hesel, biometrických údajů nebo jiných metod pro ověření identity uživatele.
Autorizace je proces řízení přístupu k informacím a zdrojům na základě ověřené identity uživatele. To zahrnuje určování, kteří uživatelé mají přístup k určitým informacím a zdrojům a jakým způsobem mohou tyto zdroje používat.
Auditování je proces sledování a zaznamenávání aktivit uživatelů na internetu. To zahrnuje zaznamenávání přístupu k informacím a zdrojům, změn v datech a dalších aktivit, které mohou mít vliv na bezpečnost informací a zdrojů.
Správné použití modelu přístupové kontroly ekosystému webu může pomoci chránit citlivé informace a zdroje před neoprávněným přístupem a zneužitím. Je důležité, aby organizace měly správné politiky a postupy pro řízení přístupu k informacím a zdrojům na internetu a aby tyto politiky a postupy byly pravidelně aktualizovány a přizpůsobeny aktuálním hrozbám v kybernetické bezpečnosti.
Single-origin policy
Single-origin policy (politika jednoho zdroje) je
bezpečnostní mechanismus v prohlížečích webových stránek, který omezuje
přístup JavaScriptu a dalším skriptovacím jazykům ke zdrojům z jiných
domén. Tento mechanismus zabraňuje útočníkům využívat kódy na jedné
stránce a aplikovat je na jinou stránku, což může vést k útokům typu
cross-site scripting (XSS) a dalším bezpečnostním hrozbám. Jedná se o
důležitý prvek v ochraně webových aplikací a uživatelských dat.
Preservations of integrity of data and code
Jedním z hlavních cílů kybernetické bezpečnosti je zajistit ochranu integrity dat a kódu. Integrity dat znamená, že data zůstanou nedotčena a nezměněna během přenosu nebo ukládání. Integrity kódu znamená, že kód zůstane nedotčen a nezměněn během vývoje, testování a nasazení.
Existuje několik způsobů, jak zajistit ochranu integrity dat a kódu:
- Šifrování: šifrování dat a kódu může pomoci chránit je před neoprávněným přístupem a úpravami.
- Digitální podpisy: digitální podpisy mohou pomoci ověřit pravost kódu a dat a zajistit, že nebyly změněny.
- Kontrola přístupu: omezení přístupu k datům a kódu může pomoci zabránit neoprávněné úpravě.
- Zálohování: pravidelné zálohování dat a kódu může pomoci obnovit původní verzi v případě útoku.
Je důležité, aby organizace měly plán na ochranu integrity dat a kódu a aby tento plán pravidelně aktualizovaly a testovaly, aby byly připraveny na případné útoky.
Sandboxing in web
Sandboxing je bezpečnostní opatření v kybernetické
bezpečnosti, které umožňuje izolovat procesy a aplikace od ostatních
částí systému. Tento koncept se nejčastěji používá v internetových
prohlížečích, kde jsou webové stránky spouštěny v izolovaném prostředí,
aby se minimalizovala možnost útoku na uživatelský systém. Sandbox
umožňuje bezpečné testování nových aplikací a softwaru, aniž by se
ohrozila bezpečnost celého systému.
Content security policy.
Content Security Policy (CSP) je bezpečnostní mechanismus, který slouží k omezení rizik spojených s útoky typu Cross-Site Scripting (XSS), Clickjacking a dalšími útoky založenými na vkládání kódu do webových stránek.
CSP umožňuje definovat, jaké zdroje jsou povoleny pro načítání na stránce, jako jsou skripty, obrázky, styly a další. To znamená, že pokud je například na stránce použit skript z externího zdroje, který není definován v CSP, bude blokován a stránka se nezobrazí.
CSP lze definovat pomocí HTTP hlavičky nebo meta tagu v HTML kódu stránky. Správné nastavení CSP může výrazně snížit riziko útoků na webové stránky a zlepšit celkovou bezpečnost aplikace.
Network protocols, TCP, DNS, BGP
Síťové protokoly jsou soubory pravidel a postupů, které umožňují komunikaci mezi počítači v síti. Tyto protokoly se používají pro přenos dat v rámci sítě a zajišťují bezpečnost a spolehlivost přenosu.
TCP
TCP (Transmission Control Protocol) je jedním z nejpoužívanějších protokolů pro přenos dat v počítačových sítích. Tento protokol zajišťuje spolehlivý přenos dat mezi počítači a kontroluje, zda dorazila všechna data bez chyb.
DNS
DNS (Domain Name System) je systém, který překládá doménová jména na IP adresy. Tento systém umožňuje počítačům v síti komunikovat s ostatními počítači pomocí doménových jmen, což je pro uživatele mnohem pohodlnější než používání IP adres.
BGP
BGP (Border Gateway Protocol) je protokol, který se používá pro směrování dat mezi autonomními systémy (AS). Tento protokol zajišťuje, že data jsou směrována správným způsobem a že jsou doručena do cílové sítě.
V kontextu kybernetické bezpečnosti jsou tyto protokoly důležité pro zajištění bezpečnosti a spolehlivosti přenosu dat. Například útoky typu DDoS mohou být zaměřeny na síťové protokoly, jako je BGP, aby způsobily výpadek sítě. Útočníci mohou také využít chyby v TCP protokolu k útoku na počítačový systém. DNS pak může být cílem útoků typu DNS spoofing, kdy útočník změní odpověď DNS serveru tak, aby uživatel byl přesměrován na škodlivou stránku. Je tedy důležité zajistit bezpečnost těchto protokolů a sledovat jejich správnou funkci.
Security of HTTPs
HTTPs je protokol pro zabezpečenou komunikaci mezi webovými servery a prohlížeči. Tento protokol zajišťuje šifrování dat, která jsou přenášena mezi serverem a prohlížečem, a tím chrání uživatele před útoky hackerů.
Jak funguje HTTPs?
Když uživatel navštíví webovou stránku s protokolem HTTPs, jeho prohlížeč zašle požadavek na server, aby zahájil zabezpečenou komunikaci. Server poté odešle certifikát, který obsahuje veřejný klíč, který bude použit k šifrování dat. Prohlížeč ověří platnost certifikátu a poté zašifruje data pomocí veřejného klíče a odešle je zpět na server. Server poté dešifruje data pomocí svého soukromého klíče.
Výhody HTTPs
Šifrování dat: HTTPs zajišťuje šifrování dat, která jsou přenášena mezi serverem a prohlížečem, a tím chrání uživatele před útoky hackerů.
Důvěryhodnost: HTTPs používá certifikáty, které jsou vydávány autorizovanými certifikačními autoritami, a tím zajišťuje důvěryhodnost webových stránek.
SEO výhody: Google preferuje webové stránky s protokolem HTTPs a tyto stránky mají větší šanci na lepší pozice ve vyhledávačích.
Závěr
HTTPs je důležitým nástrojem pro zabezpečení webových stránek a ochranu uživatelů před útoky hackerů. Použití HTTPs je dnes již standardem a každý majitel webové stránky by měl zajistit, aby jeho stránka byla chráněna touto technologií.
Mechanism of certificates
Mechanismus certifikátů je klíčovým prvkem kybernetické bezpečnosti. Certifikáty jsou digitální identifikátory, které slouží k ověření totožnosti uživatele, serveru nebo aplikace. Certifikáty se vydávají certifikačními autoritami (CA) a obsahují informace o vlastníkovi, platnosti a veřejném klíči.
Certifikáty umožňují šifrování komunikace mezi uživateli a serverem, což zajišťuje důvěrnost a integritu dat. Pokud uživatel obdrží certifikát od serveru, může se spolehnout na to, že komunikuje s legitimním serverem a že data jsou šifrována tak, aby nebyla čitelná pro neoprávněné osoby.
Pro správnou funkci certifikátů je důležité, aby byly správně vydávány, ověřovány a spravovány. Certifikační autority musí mít dostatečné zabezpečení a důvěryhodnost, aby se zabránilo podvržení certifikátů. Uživatelé musí být schopni ověřit platnost certifikátu a důvěryhodnost vydavatele.
Mechanismus certifikátů je klíčovým prvkem kybernetické bezpečnosti a je důležité, aby byl správně implementován a spravován, aby se minimalizovala rizika kybernetických útoků.
Security of certificate infrastructure.
Certifikační infrastruktura (PKI) je systém, který umožňuje vydávat a ověřovat digitální certifikáty. Tyto certifikáty jsou klíčové pro zajištění bezpečného přenosu dat na internetu. Proto je důležité zajistit bezpečnost celé PKI.
Hrozby pro certifikační infrastrukturu
Existuje několik způsobů, jak mohou být certifikační autority (CA) ohroženy:
Útoky na CA server: Hackeři mohou zaútočit na server CA a ukrást privátní klíče, které jsou potřebné k vydávání certifikátů. Pokud útočník získá tyto klíče, může vydávat falešné certifikáty a provádět útoky typu man-in-the-middle.
Útoky na uživatele: Útočníci mohou cílit na uživatele a získat jejich privátní klíče. Poté mohou vydávat falešné certifikáty a provádět útoky typu man-in-the-middle.
Útoky na certifikační řetězec: Certifikační řetězec je řada certifikátů, které jsou použity k ověření identity webové stránky. Pokud útočník získá privátní klíč jedné z certifikačních autorit v řetězci, může vydávat falešné certifikáty a provádět útoky typu man-in-the-middle.
Zabezpečení certifikační infrastruktury
Aby byla certifikační infrastruktura bezpečná, je nutné dodržovat několik zásad:
Bezpečné ukládání privátních klíčů: Privátní klíče by měly být uchovávány v bezpečném prostředí, kde mají přístup pouze oprávněné osoby.
Bezpečné ověřování uživatelů: Uživatelé by měli být ověřováni pomocí silných hesel a dvoufázové autentizace.
Kontrola certifikačního řetězce: Certifikační řetězec by měl být pravidelně kontrolován a aktualizován, aby se minimalizovalo riziko útoků.
Šifrování přenosu dat: Všechny přenosy dat by měly být šifrovány pomocí silného šifrovacího protokolu, jako je například TLS.
Pravidelné aktualizace a opravy: Certifikační infrastruktura by měla být pravidelně aktualizována a opravována, aby se minimalizovalo riziko zneužití.
Dodržování těchto zásad je klíčové pro zajištění bezpečnosti certifikační infrastruktury a ochranu před útoky.
Firewalls
Firewally jsou základním prvkem zabezpečení počítačových sítí. Jedná se o software nebo hardware, který slouží k ochraně sítě před neoprávněným přístupem. Firewall může blokovat nebo povolit přístup k určitým síťovým službám na základě definovaných pravidel.
Typy firewalů
Stavový firewall
Stavový firewall sleduje stav síťového spojení a umožňuje povolit přístup pouze k platným spojením. Tento typ firewallu je schopen rozpoznat, zda je spojení iniciováno z vnitřní nebo vnější sítě a podle toho povolit nebo blokovat přístup.
Paketový firewall
Paketový firewall pracuje na úrovni síťového protokolu a umožňuje blokovat nebo povolit přenos jednotlivých paketů na základě definovaných pravidel. Tento typ firewallu je méně sofistikovaný než stavový firewall a může být snadno překonán pokročilejšími útoky.
Aplikační firewall
Aplikační firewall pracuje na úrovni aplikace a umožňuje blokovat nebo povolit přístup k jednotlivým aplikacím nebo službám na základě definovaných pravidel. Tento typ firewallu je nejsofistikovanější a umožňuje detailní kontrolu nad síťovým provozem.
Konfigurace firewallu
Správná konfigurace firewallu je klíčová pro úspěšné zabezpečení sítě. Firewall by měl být konfigurován tak, aby blokoval veškerý nevyžádaný síťový provoz a povoloval pouze provoz, který je nezbytný pro fungování sítě. Důležité je také pravidelně aktualizovat pravidla firewallu a sledovat jeho logy pro odhalení podezřelého síťového provozu.
Network intrusion detection
Síťová detekce proniknutí (NID) je proces monitorování síťového provozu a hledání podezřelých aktivit, které by mohly naznačovat útok na síť. NID může být prováděno pomocí hardwarových zařízení nebo softwarových aplikací, které analyzují síťový provoz a hledají známky útoku.
Existuje několik typů NID, včetně detekce chování, detekce signatur a detekce anomálií. Detekce chování sleduje chování uživatelů a aplikací v síti a hledá podezřelé vzorce, jako jsou opakované pokusy o přihlášení nebo přístup k citlivým datům. Detekce signatur používá databázi známých útoků a hledá shodu mezi síťovým provozem a těmito známými útoky. Detekce anomálií sleduje neobvyklé vzorce v síťovém provozu a upozorňuje na podezřelé aktivity.
NID je důležitou součástí kybernetické bezpečnosti a pomáhá chránit organizace před útoky na síť. Správně nakonfigurovaný a spravovaný NID může identifikovat útoky včas a umožnit rychlou reakci na ně.
Network intrusion prevention
Ochrana proti vniknutí do sítě (Network intrusion prevention) je důležitou součástí kybernetické bezpečnosti. Tato technologie slouží k detekci a prevenci neoprávněného přístupu do sítě.
Jak to funguje?
Systém ochrany proti vniknutí do sítě monitoruje provoz v síti a analyzuje ho na základě předem definovaných pravidel. Pokud je detekována podezřelá aktivita, systém aktivuje bezpečnostní opatření, jako je například blokování přístupu nebo varování správce sítě.
Proč je to důležité?
Bez ochrany proti vniknutí do sítě mohou být počítače a další zařízení v síti ohroženy útoky, jako jsou například útoky typu Denial of Service (DoS) nebo ransomware. Tyto útoky mohou způsobit výpadek sítě, ztrátu dat a další škody.
Závěr
Ochrana proti vniknutí do sítě je zásadní pro zajištění kybernetické bezpečnosti. Je důležité mít tuto technologii správně nakonfigurovanou a pravidelně aktualizovanou, aby byla schopna detekovat nové hrozby a bránit se jim.
Poznámka: V češtině se také často používá termín “prevence vniknutí do sítě”.
Thin client
Tenký klient je počítačový systém, který se používá pro přístup k centrálnímu serveru. Tento typ klienta nemá vlastní pevný disk ani většinu hardwarových komponentů, což znamená, že veškeré zpracování a ukládání dat se provádí na serveru. To znamená, že tenký klient je méně náchylný na útoky a viry, protože všechna data jsou uložena na centrálním serveru a ne na samotném klientovi.
V oblasti kybernetické bezpečnosti se tenký klient používá jako jedna z možností pro zabezpečení sítě. Protože všechna data jsou uložena na serveru, mohou být snadno monitorována a chráněna před neoprávněným přístupem. Tenké klienty také umožňují snadnou aktualizaci softwaru a zabezpečení, protože všechny změny se provádějí pouze na centrálním serveru.
Celkově lze říci, že tenký klient je užitečným nástrojem pro zabezpečení sítě a prevenci kybernetických útoků.
Intrusion deflection
Odklon útoků (anglicky Intrusion deflection) je proces, při kterém se snažíme zabránit útokům na počítačové systémy. Tento proces se skládá z několika kroků:
Detekce útoku: Snažíme se identifikovat útoky, které jsou namířeny na naše systémy. K tomu můžeme použít různé nástroje, jako jsou například firewally, antiviry nebo systémy detekce anomálií.
Odpověď na útok: Jakmile identifikujeme útok, musíme na něj adekvátně reagovat. To může zahrnovat například blokování útočníka, uzavření bezpečnostních děr nebo obnovení dat ze zálohy.
Prevence budoucích útoků: Abychom minimalizovali riziko budoucích útoků, musíme zajistit, že jsou naše systémy dostatečně zabezpečené. To zahrnuje pravidelné aktualizace softwaru, silná hesla a další bezpečnostní opatření.
Odklon útoků je důležitou součástí kybernetické bezpečnosti a pomáhá chránit naše počítačové systémy před různými hrozbami, jako jsou například malware, phishing nebo DDoS útoky.
Denial of service attack
Útok typu Denial of Service (DoS) je útok, kdy útočník záměrně přetíží cílový systém, aby byl nedostupný pro legitimní uživatele. Toho lze dosáhnout různými způsoby, například pomocí floodingu síťového provozu, útoků na protokoly nebo využitím zranitelností v softwaru.
Druhy DoS útoků
Flooding útoky: Útočník přetíží síťovou linku nebo server velkým množstvím nelegitimních datových paketů. To má za následek výpadek služeb a nedostupnost systému.
Spoofing útoky: Útočník využívá zranitelností v síťových protokolech k tomu, aby posílal falešné nebo modifikované pakety, které vypadají jako legitimní. To může vést k výpadku služeb nebo k úniku citlivých informací.
Využití zranitelností: Útočník využívá zranitelnosti v softwaru nebo hardware cílového systému k tomu, aby ho donutil spadnout nebo aby získal neoprávněný přístup.
Ochrana proti DoS útokům
Monitorování sítě: Monitorování síťového provozu může pomoci odhalit DoS útoky a umožnit rychlou reakci.
Firewally: Firewally mohou být použity k blokování nelegitimního síťového provozu a ochraně proti DoS útokům.
Load balancing: Load balancing může pomoci rozložit zátěž mezi více serverů a snížit tak riziko výpadku služeb.
Aktualizace softwaru: Pravidelné aktualizace softwaru mohou pomoci snížit riziko využití zranitelností v softwaru.
Ochrana proti spoofingu: Použití technologií, jako je například DNSSEC, může pomoci chránit proti spoofingu útokům.
Využití služeb DDoS ochrany: Pokud je organizace vystavena vysokému riziku DoS útoků, může být využita služba DDoS ochrany, která poskytuje pokročilé nástroje pro detekci a obranu proti útokům.
Reflection attacks
Reflection attacks or reflected amplification attacks are a type of DDoS attack where the attacker sends a request to a server with a spoofed IP address, and the server responds to the victim with a much larger response than the original request. This causes the victim to be overwhelmed with traffic, eventually leading to denial of service.
How does it work?
- The attacker sends a request to a server with a spoofed IP address.
- The server responds to the request, but with a much larger response than the original request.
- The victim receives the amplified response, overwhelming their system and causing denial of service.
Prevention
- Implement anti-spoofing measures to prevent attackers from using spoofed IP addresses.
- Use traffic filtering to block traffic from known sources of reflection attacks.
- Use rate limiting to limit the amount of traffic that can be sent to a server in a given time period.
Syn-cookies
Syn-cookies jsou bezpečnostní opatření používaná v
počítačových sítích k ochraně před útoky typu SYN flood. Tyto útoky jsou
zaměřeny na přetížení sítě nebo serveru tím, že se zasílají velké
množství SYN požadavků, které nejsou dokončeny, což vede ke ztrátě
výkonu a výpadkům služeb.
Syn-cookies fungují tím, že místo ukládání SYN požadavků
do paměti serveru, jsou informace o těchto požadavcích zakódovány do
speciálního čísla, které je připojeno k odpovědi serveru na požadavek.
Pokud je následující požadavek na server s tímto číslem, server
rozpozná, že se jedná o platný požadavek a dokončí ho.
Tímto způsobem jsou Syn-cookies schopny odolat útokům
typu SYN flood a zajistit, že server zůstane v provozu i při velkém
množství požadavků.
Detection and protection against DOS.
DOS (Denial of Service) útoky jsou útoky, které mají za cíl zahlcení služby nebo systému, což vede k nedostupnosti pro legitimní uživatele. Pro ochranu proti těmto útokům je důležité mít implementované následující opatření:
Detekce DOS útoků
- Monitorování síťového provozu: Monitorování síťového provozu může odhalit anomálie v síťovém provozu, které mohou indikovat DOS útoky. Například velké množství paketů od jednoho zdroje nebo velké množství požadavků na konkrétní službu.
- Monitoring chování uživatelů: Monitorování chování uživatelů může odhalit neobvyklé chování, které může indikovat DOS útoky. Například uživatelé, kteří se snaží přistupovat ke službám, ke kterým nemají oprávnění.
Ochrana proti DOS útokům
- Firewall: Firewall může blokovat síťový provoz, který je považován za DOS útok. Například může blokovat síťový provoz od konkrétního zdroje nebo síťový provoz s určitými charakteristikami.
- Load balancer: Load balancer může rovnoměrně rozdělovat síťový provoz mezi více serverů, což snižuje riziko DOS útoku, protože jeden server nemůže být zahlcen.
- Cloud-based security services: Cloud-based security services mohou poskytovat ochranu proti DOS útokům tím, že poskytují škálovatelnou infrastrukturu, která může odolat vysokému objemu síťového provozu.
Poznámka: V češtině se používá termín DoS útok (Denial of Service).
DS2
Topics
Big Data concept, basic principles of distributed data processing, types and properties of NoSQL databases. BE4M36DS2 (Course web pages)
Questions
- Big Data (V characteristics, current trends), NoSQL databases (motivation, features). Scaling (vertical, horizontal, network fallacies, cluster). Distribution models (sharding, replication, master-slave and peer-to-peer architectures). CAP theorem (properties, ACID, BASE). Consistency (strong, eventual, read, write, quora). Performance tuning (Amdahl’s law, Little’s law, message cost model). Polyglot persistence.
- XPath (path expressions, axes, node tests, predicates). XQuery (constructors, FLWOR, conditional, quantified and comparison expressions). SPARQL (subgraph matching, graph patterns, datasets, filters, solution modifiers, query forms).
- RiakKV (CRUD operations, links, link walking, convergent replicated data types, Search 2.0, vector clocks, Riak Ring, replica placement strategy). Redis (data types, operations, TTL). Cassandra (keyspaces, column families, CRUD operations). MongoDB (CRUD operations, update and query operators, projection, modifiers).
- Graph data structures (adjacency matrix, adjacency list, incidence matrix). Data locality (BFS layout, bandwidth minimization problem, Cuthill-McKee algorithm). Graph partitioning (1D partitioning, 2D partitioning). Neo4j (traversal framework, traversal description, traverser). Cypher (graph matching, read, write and general clauses).
Big Data:
- 5 V charakteristiky:
- Objem (Volume): obrovské množství dat
- Rychlost (Velocity): rychlé generování a zpracování dat
- Rozmanitost (Variety): různé formáty dat (strukturovaná, nestrukturovaná)
- Pravdivost (Veracity): důvěryhodnost a kvalita dat
- Hodnota (Value): užitečnost získaných informací z dat
- Současné trendy:
- Aplikace strojového učení a umělé inteligence
- Cloud computing pro ukládání a zpracování dat
- Analýza sociálních sítí a sentimentu
- Internet věcí (IoT) a chytrá města
- Zpracování a analýza reálných časových dat
NoSQL databáze:
- Motivace:
- Potřeba zpracovávat velké objemy nestrukturovaných dat
- Rychlost a škálovatelnost
- Vyšší tolerance k chybám a výpadkům
- Flexibilita a jednoduchost v návrhu datových modelů
- Vlastnosti:
- BezSQL (Not-only-SQL): nepoužívají pouze SQL dotazy
- Škálovatelnost: horizontální škálování, distribuované prostředí
- Typy NoSQL databází: dokumentové, klíč-hodnota, sloupcové, grafové
- Eventuální konzistence: ochota obětovat striktní konzistenci za rychlost a škálovatelnost
- Snadná a rychlá integrace s Big Data aplikacemi
Škálování:
- Vertikální škálování:
- Přidávání zdrojů (CPU, paměť, úložiště) do jednoho serveru
- Omezení: fyzické limity serveru, vyšší cena, možný výpadek v provozu
- Horizontální škálování:
- Rozdělení zátěže mezi více serverů
- Výhody: lepší výkonnost, tolerance k výpadkům, snadné přidání dalších serverů
- Nevýhody: složitější správa, potřeba distribuovaných systémů
Síťové klamání (Network Fallacies):
- Spolehlivost sítě
- Nulová latence
- Nekonečná šířka pásma
- Bezpečná síť
- Homogenita sítě
Cluster (shluk):
- Skupina propojených serverů pracujících společně jako jeden systém
- Výhody:
- Zvýšení výkonnosti a zátěžové kapacity
- Tolerance k výpadkům a zajištění dostupnosti
- Snadné škálování
- Nevýhody:
- Složitější správa a konfigurace
- Vyšší náklady na hardware a software
Distribuční modely:
- Sharding:
- Rozdělení dat do menších částí (shard) a uložení na různých serverech
- Výhody: zvýšení výkonnosti, snížení zátěže, snadné škálování
- Nevýhody: složitější správa, náročnější na vývoj aplikací
- Replikace:
- Více kopírování dat mezi servery pro zajištění dostupnosti a zálohy
- Výhody: zvýšení odolnosti vůči výpadkům, snížení zátěže
- Nevýhody: zvýšení nákladů na úložiště, režie při synchronizaci dat
Architektury:
- Master-Slave:
- Jeden hlavní server (master) a jeden nebo více záložních serverů (slave)
- Master: spravuje zápis dat, synchronizuje s Slave servery
- Slave: pouze čtení dat, záložní server pro případ výpadku Master serveru
- Výhody: zvýšení výkonnosti, snížení zátěže, jednoduchá správa
- Nevýhody: možný úzký hrdlo (master), složitější zápis dat
- Peer-to-Peer (P2P):
- Síť, ve které každý uzel komunikuje přímo s ostatními uzly
- Žádný ústřední server nebo autorita
- Výhody: škálovatelnost, odolnost vůči výpadkům, decentralizace
- Nevýhody: složitější správa, zvýšená režie při komunikaci mezi uzly
CAP věta:
- Vlastnosti:
- Konzistence (Consistency): každý uzel v síti vidí stejná data
- Dostupnost (Availability): každý dotaz na systém dostane odpověď
- Tolerance k rozdělení (Partition Tolerance): systém funguje i při výpadcích části sítě
- CAP věta: v distribuovaném systému nelze zaručit všechny tři vlastnosti současně, pouze dvě z nich
ACID:
- Vlastnosti transakcí v tradičních (SQL) databázích:
- Atomicita (Atomicity): transakce je buď celá provedena nebo vůbec
- Konzistence (Consistency): databáze zůstane konzistentní po každé transakci
- Izolace (Isolation): paralelní transakce se neovlivňují navzájem
- Trvanlivost (Durability): potvrzené transakce jsou trvale uloženy
BASE:
- Vlastnosti transakcí v NoSQL databázích:
- Základní dostupnost (Basically Available): systém je dostupný i při výpadcích části sítě
- Měkká stavovost (Soft State): stav systému se může měnit časem, i bez vstupu
- Eventuální konzistence (Eventual Consistency): konzistence dat je zaručena po určitém čase
- BASE je obětování konzistence za dostupnost a toleranci k rozdělení (oproti ACID)
Konzistence:
- Silná konzistence (Strong Consistency):
- Každý čtenář vidí nejnovější zápis nebo chybu
- Zaručuje, že všechny uzly v distribuovaném systému zobrazují stejná data
- Může mít negativní dopad na výkonnost a škálovatelnost
- Eventuální konzistence (Eventual Consistency):
- Zaručuje, že všechny změny budou nakonec propagovány do všech uzlů
- Nezaručuje okamžitou konzistenci dat, ale po určitém čase
- Výhody: rychlost, škálovatelnost, flexibilita
- Používáno v NoSQL databázích a BASE systémech
Konzistence čtení a zápisu:
- Čtenářská konzistence (Read Consistency):
- Zajišťuje, že čtenář vidí data konzistentní s posledním zápisem
- Zápisová konzistence (Write Consistency):
- Zajišťuje, že zápis dat je proveden konzistentně napříč všemi uzly
Kvóra (Quorum):
- Mechanismus pro dosažení konzistence v distribuovaných systémech
- Založeno na hlasování uzlů pro potvrzení čtení a zápisu
- R > W: silná konzistence čtení, slabá konzistence zápisu
- W > R: slabá konzistence čtení, silná konzistence zápisu
- R + W > N: silná konzistence čtení i zápisu, kde N je počet uzlů
Optimalizace výkonu:
- Amdahlův zákon:
- Popisuje vliv paralelizace na zrychlení výpočtu
- Zákon: S = 1 / (P + (1 - P) / N)
- S: zrychlení výpočtu
- P: podíl části úkolu, která nemůže být paralelizována
- N: počet procesorů
- Ukazuje, že zrychlení je omezeno sériovou částí úkolu
- Littleův zákon:
- Popisuje vztah mezi počtem přítomných požadavků, rychlostí zpracování a dobou odezvy
- Zákon: L = λW
- L: průměrný počet požadavků v systému
- λ: rychlost příchodu nových požadavků (požadavky za jednotku času)
- W: průměrná doba odezvy na požadavek
- Používá se pro optimalizaci front, zpracování požadavků a plánování zdrojů
- Model nákladů na zprávy (Message Cost Model):
- Model pro analýzu komunikačních nákladů v distribuovaných systémech
- Faktory ovlivňující náklady:
- Latence: čas potřebný pro doručení zprávy
- Šířka pásma: přenosová rychlost mezi uzly
- Režie: zpracování zpráv na odesílacím a přijímacím uzlu
- Pomáhá optimalizovat komunikaci mezi uzly a snižovat dobu odezvy
MapReduce (architecture, functions, data flow, execution, use cases). Hadoop (MapReduce, HDFS).
MapReduce:
- Architektura:
- Programovací model pro paralelní a distribuované zpracování velkého množství dat
- Skládá se ze dvou hlavních funkcí: Map a Reduce
- Obvykle se provádí na clusterech
- Funkce:
- Map: zpracování vstupních dat, transformace na páry klíč-hodnota
- Reduce: agregace páru klíč-hodnota podle klíče a výpočet výsledku
- Datový tok:
- Vstupní data jsou rozdělena do částí (shard)
- Map funkce se spustí na každém shardu paralelně a generuje páry klíč-hodnota
- Páry klíč-hodnota jsou seskupeny podle klíčů
- Reduce funkce zpracovává seskupené páry klíč-hodnota a vypočítá výsledky
- Provedení:
- Job Tracker: koordinuje celý proces, rozděluje úkoly, sleduje pokrok
- Task Tracker: zpracovává map a reduce úkoly na jednotlivých uzlech
- Příklady použití:
- Analýza textu a počítání slov
- Zpracování log souborů a analýza webového provozu
- Vyhledávání vzorů v datech
- Strojové učení a statistické analýzy
Hadoop:
- Open-source framework pro distribuované zpracování velkého množství dat
- Hlavní komponenty:
- Hadoop MapReduce
- Hadoop Distributed File System (HDFS)
Hadoop MapReduce:
- Implementace MapReduce modelu pro zpracování dat v Hadoopu
- Řídí paralelní zpracování dat pomocí map a reduce funkcí
- Podporuje škálování, odolnost vůči výpadkům a distribuci dat
HDFS - Hadoop Distributed File System:
- Hlavní komponenty HDFS:
- NameNode
- DataNode
- NameNode:
- Ústřední server pro správu metadata souborového systému
- Udržuje informace o adresářové struktuře, právech, a umístění bloků dat
- Komunikuje s DataNode pro správu uložených dat
- HDFS může mít jednu aktivní a jednu nebo více pasivních (záložních) NameNode
- Pasivní NameNode synchronizuje data s aktivní NameNode pro zajištění odolnosti vůči výpadkům
- DataNode:
- Servery, které skutečně ukládají data na disky
- Data jsou uložena ve formě bloků s pevnou velikostí (např. 64 MB nebo 128 MB)
- DataNode komunikuje s NameNode a zpracovává požadavky na čtení/zápis dat
- Data jsou automaticky replikována na více DataNode pro zajištění dostupnosti a odolnosti vůči výpadkům
- Práce s HDFS:
- Uživatel pošle požadavek na čtení/zápis dat na NameNode
- NameNode zkontroluje metadata a v případě zápisu vybere vhodné DataNode pro uložení dat
- Uživatel komunikuje přímo s vybranými DataNode pro čtení nebo zápis dat
- Po dokončení zápisu informuje DataNode NameNode o úspěšném uložení dat
- HDFS je navržen pro:
- Ukládání velkých souborů
- Paralelní zpracování dat
- Vysokou propustnost a odolnost vůči výpadkům
- Integraci s Hadoop MapReduce pro efektivní zpracování dat
XPath
- XPath
- Cesta vyjadřuje umístění uzlů v XML dokumentu
- Používá se pro vyhledávání dat v XML dokumentech
- Výrazy cesty
- Absolutní: Začínají od kořenového uzlu (např.
/kniha/nazev) - Relativní: Začínají od aktuálního uzlu (např.
./nazev)
- Absolutní: Začínají od kořenového uzlu (např.
- Osi
- child: Bezprostřední potomci aktuálního uzlu
- descendant: Všichni potomci aktuálního uzlu
- parent: Rodič aktuálního uzlu
- ancestor: Všichni předkové aktuálního uzlu
- sibling: Sourozenci aktuálního uzlu
- Testy uzlů
- node(): Vybere všechny uzly
- text(): Vybere všechny textové uzly
- comment(): Vybere všechny komentářové uzly
- processing-instruction(): Vybere všechny uzly zpracovávající pokyny
- Predikáty
- Umožňují filtrovat výsledky XPath výrazů
- Uzavírají se do hranatých závorek (např.
/kniha[nazev='Mistr a Markétka']) - Často se používají s operátory a funkcemi (např.
not(),and,or)
XQuery
- XQuery
- Jazyk pro dotazování a manipulaci s XML a JSON dokumenty
- Má vyšší výrazovou sílu než XPath
- Konstruktory
- Element:
<jmeno>{obsah}</jmeno> - Atribut:
attribute jmeno {"hodnota"} - Text:
text {"obsah"} - Komentář:
comment {"komentář"} - Zpracovávací pokyn:
processing-instruction jmeno {"hodnota"}
- Element:
- FLWOR
- Pro vyhledávání a transformaci dat
- F: For - prochází kolekcemi
- L: Let - přiřazuje hodnotu proměnné
- W: Where - podmínka pro filtrování
- O: Order by - řazení výsledků
- R: Return - vrácení výsledku
- Podmínkové výrazy
- if (podmínka) then (výraz1) else (výraz2)
- Kvantifikované výrazy
- every $x in (sekvence) satisfies (podmínka)
- some $x in (sekvence) satisfies (podmínka)
- Porovnávací výrazy
- ‘=’, ‘!=’, ‘<’, ‘>’, ‘<=’, ‘>=’
- ‘eq’, ‘ne’, ‘lt’, ‘gt’, ‘le’, ‘ge’
SPARQL
- SPARQL
- Jazyk pro dotazování a manipulaci s RDF grafovými daty
- Používá se pro práci s daty ve formátu RDF
- Subgrafické porovnávání
- Hledání vzorů v RDF grafech
- Provádí se pomocí trojic subjekt-predikát-objekt
- Grafové vzory
- Základní: Jednoduché trojice (např.
?x rdf:type foaf:Person) - Volitelné: Používají klíčové slovo OPTIONAL (např.
OPTIONAL {?x foaf:mbox ?email}) - Alternativní: Používají klíčové slovo UNION (např.
{?x foaf:name ?name} UNION {?x rdfs:label ?name})
- Základní: Jednoduché trojice (např.
- Datasety
- Default: Graf, který je vyhledáván implicitně
- Named: Grafy, které jsou vyhledávány explicitně pomocí klíčového slova FROM NAMED
- Filtry
- Omezují výsledky dotazu podle zadaných podmínek
- Používají klíčové slovo FILTER (např.
FILTER (?age >= 18))
- Modifikátory řešení
- Order by: Řazení výsledků (např.
ORDER BY ?name) - Limit: Omezení počtu výsledků (např.
LIMIT 10) - Offset: Posunutí výsledků (např.
OFFSET 5) - Distinct: Odstranění duplikátů (např.
SELECT DISTINCT ?name)
- Order by: Řazení výsledků (např.
- Formy dotazů
- SELECT: Výběr proměnných
- CONSTRUCT: Vytváření nových RDF trojic
- ASK: Dotaz na existenci vzoru
- DESCRIBE: Popis zdrojů RDF
RiakKV
- RiakKV
- Distribuovaný klíč-hodnota úložiště
- Navržený pro vysokou dostupnost a škálovatelnost
- CRUD operace
- Create: Vytvoření hodnoty s klíčem
- Read: Čtení hodnoty podle klíče
- Update: Aktualizace hodnoty s klíčem
- Delete: Smazání hodnoty s klíčem
- Odkazy (links)
- Reprezentují vztahy mezi objekty v RiakKV
- Umožňují navigaci mezi objekty
- Procházení odkazů (link walking)
- Prohledávání objektů v RiakKV pomocí odkazů
- Zahrnuje kroky ve formátu “kbelík,tag,řetězec”
- Konvergentní replikované datové typy (CRDT)
- Umožňují konzistentní replikaci dat v distribuovaném systému
- Zahrnuje: množiny, mapy, flagy, registry a čítače
- Search 2.0
- Full-textové vyhledávání v RiakKV
- Založeno na Apache Solr
- Vektorové hodiny (vector clocks)
- Algoritmus pro řešení konfliktů v distribuovaném systému
- Sleduje verze objektů a řeší konflikty
- Riak Ring
- Struktura pro rozdělení dat v RiakKV
- Zajišťuje škálovatelnost a toleranci selhání
- Strategie umístění replik (replica placement strategy)
- Určuje, jak a kde jsou repliky uloženy v RiakKV
- Zahrnuje: uniformní, zónování a vlastní strategie
Redis
- Redis
- Výkonný klíč-hodnota úložiště v paměti
- Podporuje rozmanité datové typy
- Datové typy
- Řetězce (strings)
- Seznamy (lists)
- Množiny (sets)
- Uspořádané množiny (sorted sets)
- Mapy (hashes)
- Bitmapy (bitmaps)
- HyperLogLogs
- Operace
- GET, SET: Čtení a zápis řetězců
- LPUSH, RPUSH, LPOP, RPOP: Práce se seznamy
- SADD, SREM, SISMEMBER: Práce s množinami
- ZADD, ZRANK, ZRANGE: Práce s uspořádanými množinami
- HSET, HGET, HDEL: Práce s mapami
- TTL (Time-To-Live)
- Expirace klíčů po určité době
- SETEX, PSETEX: Nastavení TTL při zápisu
- EXPIRE, PEXPIRE: Nastavení TTL pro existující klíč
- TTL, PTTL: Získání zbývajícího času do expirace
Cassandra
- Cassandra
- Distribuovaná databáze s vysokou škálovatelností a dostupností
- Navržená pro práci s velkým množstvím dat
- Keyspaces
- Kontejnery pro ukládání sloupcových rodin (column families)
- Definují replikační faktor a strategii
- Column families
- Ukládají data v Cassandra
- Skládají se ze sloupců a řádků
- CRUD operace
- CREATE: Vytvoření keyspace, tabulky nebo indexu
- INSERT: Vložení nebo aktualizace záznamu
- SELECT: Čtení záznamů
- UPDATE: Aktualizace záznamu
- DELETE: Smazání záznamu nebo části záznamu
MongoDB
- MongoDB
- Dokumentová databáze s vysokou škálovatelností a flexibilitou
- Ukládá data ve formátu BSON (binární JSON)
- CRUD operace
- Create: Vytvoření dokumentu (db.kolekce.insert())
- Read: Čtení dokumentů (db.kolekce.find())
- Update: Aktualizace dokumentů (db.kolekce.update())
- Delete: Smazání dokumentů (db.kolekce.remove())
- Operátory aktualizace
- $set: Nastavení hodnoty pole nebo vytvoření nového pole
- $unset: Odstranění pole
- $inc: Inkrementace hodnoty pole
- $mul: Násobení hodnoty pole
- $rename: Přejmenování pole
- Operátory dotazování
- $eq: Rovnost
- $gt, $gte: Větší než, větší než nebo rovno
- $lt, $lte: Menší než, menší než nebo rovno
- $ne: Nerovnost
- $in: Hodnota je v seznamu
- $nin: Hodnota není v seznamu
- $and, $or, $not: Logické operátory
- Projekce
- Určuje, která pole vrátit v dotazu
- 1 pro zobrazení pole, 0 pro skrytí pole (např.
{pole: 1})
- Modifikátory
- $limit: Omezení počtu vrácených dokumentů
- $skip: Přeskočení určitého počtu dokumentů
- $sort: Řazení dokumentů podle zadaných kritérií
Grafové datové struktury
- Grafové datové struktury
- Používány pro reprezentaci grafů (sítí, diagramů) v paměti počítače
- Základní struktury: maticová a seznamová reprezentace
- Matice sousednosti (adjacency matrix)
- Čtvercová matice, která popisuje vztahy mezi vrcholy grafu
- V[i][j] = 1, pokud vrcholy i a j sousedí, jinak 0
- Pro vážené grafy: V[i][j] = váha hrany, pokud vrcholy i a j sousedí, jinak 0
- Výhody:
- Rychlé zjištění, zda mezi vrcholy existuje hrana
- Jednoduchá implementace
- Nevýhody:
- Nevhodné pro řídké grafy (mnoho nulových hodnot)
- Vyšší paměťová náročnost
- Seznam sousednosti (adjacency list)
- Pole seznamů, kde každý seznam obsahuje sousedy daného vrcholu
- V[i] = seznam sousedních vrcholů vrcholu i
- Pro vážené grafy: V[i] = seznam dvojic (soused, váha hrany)
- Výhody:
- Nižší paměťová náročnost pro řídké grafy
- Rychlé procházení sousedů daného vrcholu
- Nevýhody:
- Pomalejší zjištění, zda mezi vrcholy existuje hrana
- Složitější implementace
- Matice incidence (incidence matrix)
- Matice, která popisuje vztahy mezi vrcholy a hranami grafu
- V[i][j] = 1, pokud vrchol i je spojen s hranou j, jinak 0
- Pro orientované grafy: V[i][j] = -1, pokud hrana j vychází z vrcholu i; V[i][j] = 1, pokud hrana j vstupuje do vrcholu i
- Výhody:
- Jednoznačně reprezentuje orientované i neorientované grafy
- Umožňuje rychle zjistit, které vrcholy jsou spojeny s danou hranou
- Nevýhody:
- Vyšší paměťová náročnost než seznam sousednosti
- Pomalejší procházení sousedů daného vrcholu
Data locality
- Data locality
- Optimalizace přístupu k datům v počítačové paměti
- Zlepšuje výkon a efektivitu paměti
- BFS layout (Breadth-First Search)
- Uspořádání dat v paměti podle BFS procházení grafu
- Výhody:
- Zlepšuje data locality pro algoritmy založené na BFS
- Snížení latence při přístupu k sousedním vrcholům
- Bandwidth minimization problem
- Problém minimalizace šířky pásma matice
- Cílem je přeuspořádat řádky a sloupce matice tak, aby neprázdné prvky byly co nejblíže hlavní diagonále
- Redukce šířky pásma zlepšuje data locality
- Cuthill-McKee algoritmus
- Heuristický algoritmus pro řešení problému minimalizace šířky pásma
- Postup:
- Vyberte vrchol s nejnižším stupněm jako kořen
- Proveďte BFS procházení grafu od kořene
- Přeuspořádejte vrcholy podle BFS pořadí
- Výhody:
- Snadno implementovatelný
- Zpravidla dává dobré výsledky
- Nevýhody:
- Ne vždy najde optimální řešení
Graph partitioning
- Grafové rozdělení (Graph partitioning)
- Proces rozdělení grafu na menší části (partice) s cílem optimalizovat výkon
- Používá se při paralelizaci, distribuovaném zpracování a zefektivnění úložiště
- 1D rozdělení (1D partitioning)
- Graf je rozdělen na partice podél jednoho rozměru (řádky nebo sloupce)
- Používá se např. při rozdělení matice na bloky pro paralelní zpracování
- Výhody:
- Jednoduchá implementace
- Snadné rozdělení zátěže mezi procesory nebo uzly
- Nevýhody:
- Může vést k nerovnoměrnému rozložení zátěže, pokud graf není rovnoměrně rozdělitelný
- Méně efektivní pro grafy s nerovnoměrným rozložením hran
- 2D rozdělení (2D partitioning)
- Graf je rozdělen na partice podél dvou rozměrů (řádky a sloupce)
- Výhody:
- Lepší vyvážení zátěže než u 1D rozdělení
- Efektivnější pro grafy s nerovnoměrným rozložením hran
- Nevýhody:
- Složitější implementace
- Vyšší režie při komunikaci mezi procesory nebo uzly
Neo4j
- Neo4j
- Grafická databáze s vysokou škálovatelností a flexibilitou
- Umožňuje efektivní prohledávání a manipulaci s grafy
- Traversal framework
- Rámec pro průchod grafem v Neo4j
- Umožňuje efektivně a flexibilně procházet grafem za účelem hledání vzorů, cest a dalších struktur
- Traversal description (Popis průchodu)
- Definuje, jak má být graf procházen
- Specifikuje:
- Výchozí vrcholy (start nodes)
- Procházení směrem (vstupní/výstupní hrany)
- Typy hran a vrcholů, které mají být zahrnuty
- Hloubka průchodu (maximální počet kroků)
- Evaluatory a pravidla pro zahrnutí vrcholů a hran do výsledku
- Traverser
- Objekt, který provádí průchod grafem podle zadaného traversal description
- Vrací výsledné vrcholy a hrany, které splňují zadaná pravidla
- Umožňuje iterativní přístup k výsledkům průchodu
Cypher
- Cypher
- Deklarativní jazyk pro práci s grafy v Neo4j
- Umožňuje jednoduché a efektivní dotazování a manipulaci s grafy
- Graph matching
- Prohledávání grafu za účelem nalezení vzorů a struktur
- Používá ASCII-art notaci pro definici vzorů
- Např.
(a)-[:ZNÁ]->(b)najde všechny vrcholyaab, které jsou spojeny hranou typu “ZNÁ”
- Read clauses (Přečíst klauzule)
- Klauzule pro čtení dat z grafu
- MATCH: Hledání vzorů v grafu
- WHERE: Filtrování výsledků podle zadaných podmínek
- RETURN: Vracení výsledků dotazu
- WITH: Průběžné zpracování výsledků (řazení, filtrování, aliasy)
- UNWIND: Rozbalení seznamů na jednotlivé prvky
- SKIP, LIMIT: Omezení počtu vrácených výsledků
- ORDER BY: Řazení výsledků podle zadaných kritérií
- Write clauses (Zapsat klauzule)
- Klauzule pro zápis a manipulaci dat v grafu
- CREATE: Vytvoření nových vrcholů a hran
- MERGE: Vytvoření vrcholu nebo hrany, pokud neexistuje, jinak aktualizace
- SET: Nastavení vlastností vrcholů a hran
- DELETE: Smazání vrcholů a hran
- REMOVE: Odstranění vlastností nebo štítků z vrcholů
- General clauses (Obecné klauzule)
- Klauzule pro řízení dotazů a nastavení
- USING INDEX: Vynucení použití indexu pro dotaz
- CALL: Volání uložených procedur a funkcí
- LOAD CSV: Načítání dat ze CSV souboru
- FOREACH: Provedení akce pro každý prvek seznamu
ESW
Topics
Effective algorithms and optimization methods. Data structures, synchronization and multithreaded programs. BE4M36ESW (Course web pages)
Questions
- Java Virtual Machine, memory layout, frame, stack-oriented machine processing, ordinary object pointer, compressed ordinary object pointer. JVM bytecode, Just-in-time compiler, tired compilation, on-stack replacement, disassembler, decompiler. Global and local safe point, time to safe point. Automatic memory Management, generational hypothesis, garbage collectors. CPU and memory profiling, sampling and tracing approach, warm-up phase.
- Data races, CPU pipelining and superscalar architecture, memory barrier, volatile variable. Synchronization - thin, fat and biased locking, reentrant locks. Atomic operations based on compare-and-set instructions, atomic field updaters. Non-blocking algorithms, wait free algorithms, non-blocking stack (LIFO).
- Static and dynamic memory analysis, shallow and retained size, memory leak. Data Structures, Java primitives and objects, auto-boxing and unboxing, memory efficiency of complex data structures. Collection for performance, type specific collections, open addressing hashing, collision resolution schemes. Bloom filters, complexity, false positives, bloom filter extensions. Reference types - weak, soft, phantom.
- JVM object allocation, thread-local allocation buffers, object escape analysis, data locality, non-uniform memory allocation.
- Networking, OSI model, C10K problem. Blocking and non-blocking input/output, threading server, event-driven server. Event-based input/output approaches. Native buffers in JVM, channels and selectors.
- Synchronization in multi-threaded programs (atomic operations, mutex, semaphore, rw-lock, spinlock, RCU). When to use which mechanism? Performance bottlenecks of the mentioned mechanisms. Synchronization in “read-mostly workloads”, advantages and disadvantages of different synchronization mechanisms.
- Cache-efficient data structures and algorithms (e.g., matrix multiplication). Principles of cache memories, different kinds of cache misses. Self-evicting code, false sharing – what is it and how deal with it?
- Profiling and optimizations of programs in compiled languages (e.g., C/C++). Hardware performance counters, profile-guided optimization. Basics of C/C++ compilers, AST, intermediate representation, high-level and low-level optimization passes.
Java Virtual Machine (JVM) a paměťové rozložení:
- JVM:
- Virtuální stroj, který umožňuje spouštět Java aplikace
- Nezávislý na platformě
- Překládá Java bytecode do strojového kódu pro konkrétní systém
- Paměťové rozložení:
- Skládá se z následujících oblastí:
- Metodický (Method) area
- Heap (Haldy)
- Java stacks
- PC (Program Counter) registry
- Nativní (Native) metoda stacks
- Skládá se z následujících oblastí:
- Heap (Haldy)
- New Generation:
- Mladší generace, kde se ukládají nově vytvořené objekty
- Dále rozdělen na:
- Eden Space: místo pro vytváření nových objektů
- Survivor Spaces (S0 a S1): oblasti pro přeživší objekty z Eden Space
- Old Generation:
- Starší generace, kam se přesouvají objekty, které přežily několik cyklů Garbage Collection
- Slouží pro dlouhodobě žijící objekty
- New Generation:
- Frame:
- Jednotka paměťového zásobníku (stack) pro každé volání metody
- Obsahuje:
- Lokální proměnné
- Operandový zásobník
- Odkaz na runtime konstantní pool
- Při volání metody se vytváří nový rámec
- Po dokončení metody se rámec uvolní z paměti

Zásobníkově orientované stroje (Stack-oriented machine processing):
- Typ architektury stroje, který využívá zásobník pro provádění operací
- Vlastnosti:
- Většina operací pracuje s daty na vrcholu zásobníku
- Instrukce nemají explicitní registry pro uchovávání operandů
- Operandy jsou načteny na zásobník a výsledky operací jsou uloženy zpět na zásobník
- Proces zpracování:
- Načtení operandů na vrchol zásobníku
- Provedení operace s vrchními prvky zásobníku
- Uložení výsledku operace zpět na vrchol zásobníku
- Výhody:
- Menší a jednodušší instrukční sada
- Snadnější implementace v hardwaru nebo softwaru
- Nevýhody:
- Méně efektivní zpracování dat kvůli častému přesouvání dat na zásobníku
- Může být pomalejší než registry orientované stroje pro některé úkoly
Běžný ukazatel na objekt (Ordinary Object Pointer):
- Ukazatel (nebo reference) používaný pro přístup k objektům v paměti
- Vlastnosti:
- Umožňuje přímý přístup k objektu v paměti
- Obvykle obsahuje adresu objektu v paměti
- V některých jazycích (např. Java) může být ukazatel automaticky aktualizován při přesunu objektu (např. během Garbage Collection)
- Použití:
- Pro přístup k atributům objektu
- Pro volání metod objektu
- Pro předávání objektů jako parametrů funkcí nebo metod
- Bezpečnost:
- V některých jazycích (např. Java, C#) jsou ukazatele na objekty automaticky spravovány a nemohou být modifikovány programátorem
- V jiných jazycích (např. C, C++) může být práce s ukazateli riskantní kvůli možnosti chyb v alokaci nebo dealokaci paměti
Komprimovaný ukazatel na objekt (Compressed Ordinary Object Pointer):
- Speciální typ ukazatele na objekt, který šetří paměťový prostor
- Princip:
- Místo ukládání celé adresy objektu v paměti, ukládá pouze část adresy
- Tím šetří paměťový prostor při uložení ukazatelů
- Využití:
- Často používán v prostředích s omezenou pamětí, jako jsou embedded systémy nebo JVM s velkou haldou
- Proces:
- Komprese: při vytvoření ukazatele se adresa objektu komprimuje a uloží do komprimovaného ukazatele
- Dekomprese: při přístupu k objektu se komprimovaná adresa dekomprimuje, čímž se získá původní adresa objektu v paměti
- Výhody:
- Šetří paměťový prostor
- Může zlepšit výkon díky menšímu množství paměťových přístupů
- Nevýhody:
- Potřeba provádět kompresi a dekompresi při práci s ukazateli
- Omezený rozsah adres, ke kterým lze přistupovat pomocí komprimovaných ukazatelů (závisí na velikosti komprimovaného ukazatele)
JVM Bytecode:
- Středně-úrovňový kód generovaný překladačem Java (javac) z Java zdrojového kódu
- Vlastnosti:
- Platformově nezávislý
- Interpretován nebo kompilován do strojového kódu pomocí Java Virtual Machine (JVM)
- Instrukce o délce 1 bajtu (byte), odtud název bytecode
- Struktura:
- Sestává z posloupnosti instrukcí, které mohou zahrnovat:
- Načítání a ukládání proměnných
- Aritmetické a logické operace
- Kontrola toku (podmínky, smyčky)
- Volání metod
- Práce s objekty a třídami
- Sestává z posloupnosti instrukcí, které mohou zahrnovat:
- Proces:
- Překlad: Java zdrojový kód je přeložen do bytecode pomocí javac
- Načtení: Bytecode je načten do JVM
- Interpretace nebo kompilace: Bytecode je interpretován nebo kompilován do strojového kódu pomocí JVM
- Spuštění: Strojový kód je spuštěn na cílovém systému
- Výhody:
- Platformová nezávislost
- Snadný přenos mezi různými systémy
- Možnost optimalizace během kompilace do strojového kódu
- Nevýhody:
- Pomalejší než nativní strojový kód
- Vyžaduje instalaci JVM na cílovém systému
Just-In-Time (JIT) kompilátor:
- Kompilátor, který kompiluje kód za běhu programu místo před jeho spuštěním
- Princip:
- Kompilace zdrojového kódu do nativního strojového kódu za běhu programu
- Probíhá dynamicky, “na požádání”
- Proces:
- Načtení: Zdrojový kód je načten do virtuálního stroje nebo runtime prostředí
- Interpretace: Zdrojový kód je nejprve interpretován
- Profiling: Během interpretace je prováděn profiling kódu pro zjištění často volaných částí (hotspots)
- Kompilace: JIT kompilátor kompiluje často volané části zdrojového kódu do nativního strojového kódu
- Spuštění: Nativní strojový kód je spuštěn na cílovém systému
- Příklad: Java Virtual Machine (JVM) používá JIT kompilátor pro kompilaci Java bytecode do nativního strojového kódu za běhu
- Výhody:
- Rychlejší běh programu než při pouhé interpretaci
- Možnost optimalizace kódu za běhu na základě aktuálního chování programu
- Přizpůsobení kódu specifickým vlastnostem hardware a operačního systému za běhu
- Nevýhody:
- Vyšší režie při kompilaci za běhu, což může zpomalit spuštění programu
- Vyžaduje více paměti pro uchování kompilovaného kódu
Tiered Compilation (Stupňovitá kompilace):
- Technika používaná u Just-In-Time (JIT) kompilátorů, která kombinuje různé úrovně optimalizace
- Princip:
- Kód je postupně kompilován a optimalizován na základě jeho výkonu a četnosti volání
- Používá více úrovní kompilace s různými úrovněmi optimalizace
- Proces:
- Načtení: Zdrojový kód je načten do virtuálního stroje nebo runtime prostředí
- Interpretace: Zdrojový kód je nejprve interpretován
- Nízkoúrovňová kompilace: Často volané části kódu jsou kompilovány s nízkou úrovní optimalizace (rychlejší kompilace, méně optimalizací)
- Profiling: Během běhu programu se sbírají informace o výkonu kompilovaného kódu
- Vysokoúrovňová kompilace: Pokud je to výhodné, části kódu mohou být kompilovány s vyšší úrovní optimalizace (pomalejší kompilace, více optimalizací)
- Příklad: Java Virtual Machine (JVM) podporuje tiered compilation v rámci svého JIT kompilátoru
- Výhody:
- Rychlejší spuštění programu díky rychlé nízkoúrovňové kompilaci
- Možnost využít vysokoúrovňové optimalizace pro části kódu, které mají zásadní vliv na výkon programu
- Lepší vyvážení mezi rychlostí kompilace a výkonem programu
- Nevýhody:
- Vyšší režie při provádění více úrovní kompilace a profilingu za běhu programu
- Vyžaduje více paměti pro uchování kompilovaného kódu a profilingových dat
On-Stack Replacement (OSR):
- Technika používaná v Just-In-Time (JIT) kompilátorech pro optimalizaci běžících funkcí za běhu programu
- Princip:
- Nahrazuje aktuálně běžící funkci (interpretovanou nebo kompilovanou s nižší úrovní optimalizace) její optimalizovanou verzí
- Umožňuje získat výhody optimalizací i pro dlouho běžící funkce
- Proces:
- Profiling: Během běhu programu se sbírají informace o výkonu funkcí
- Optimalizace: JIT kompilátor kompiluje optimalizovanou verzi funkce
- Nahrazení: Aktuálně běžící funkce je nahrazena optimalizovanou verzí
- Spuštění: Optimalizovaná funkce pokračuje v běhu od místa, kde byla původní funkce přerušena
- Příklad: Java Virtual Machine (JVM) podporuje on-stack replacement v rámci svého JIT kompilátoru
- Výhody:
- Zlepšení výkonu dlouho běžících funkcí díky optimalizacím
- Umožňuje aplikovat optimalizace za běhu programu bez nutnosti restartu
- Nevýhody:
- Vyšší režie při provádění nahrazení běžící funkce
- Složitost implementace OSR ve virtuálním stroji nebo JIT kompilátoru
Disassembler
- Nástroj, který převádí strojový kód nebo spustitelný soubor zpět na čitelnější formát, jako je assembler
- Princip:
- Analyzuje strojový kód a hledá odpovídající assemblerové instrukce
- Vytváří textový výstup s assemblerovým kódem a dalšími informacemi, jako jsou adresy, hodnoty registrů, atd.
- Proces:
- Načtení: Disassembler načte strojový kód nebo spustitelný soubor
- Dekódování: Strojové instrukce jsou dekódovány na odpovídající assemblerové instrukce
- Výstup: Výsledný assemblerový kód je zobrazen nebo uložen do souboru
- Použití:
- Analýza a ladění spustitelných souborů
- Zjištění funkcionality neznámého nebo podezřelého kódu (např. malware)
- Reverzní inženýrství, zkoumání algoritmů a optimalizací v cizím kódu
- Výhody:
- Umožňuje získat vhled do chování strojového kódu nebo spustitelného souboru
- Pomáhá při analýze a ladění programů
- Nevýhody:
- Assemblerový kód je obtížnější číst a porozumět než zdrojový kód vysokoúrovňových jazyků
- Ztráta informace o proměnných, funkcích a komentářích, které byly v původním zdrojovém kódu
- Může být omezen na konkrétní architekturu nebo operační systém
Decompiler
- Nástroj, který převádí strojový kód nebo spustitelný soubor zpět na zdrojový kód vysokoúrovňového programovacího jazyka
- Princip:
- Analyzuje strojový kód a rekonstruuje odpovídající zdrojový kód vysokoúrovňového jazyka
- Vytváří textový výstup se zdrojovým kódem a dalšími informacemi, jako jsou názvy proměnných, funkce, atd.
- Proces:
- Načtení: Dekompilátor načte strojový kód nebo spustitelný soubor
- Dekódování: Strojové instrukce jsou dekódovány a zkonstruován odpovídající zdrojový kód vysokoúrovňového jazyka
- Výstup: Výsledný zdrojový kód je zobrazen nebo uložen do souboru
- Použití:
- Analýza a ladění spustitelných souborů
- Zjištění funkcionality neznámého nebo podezřelého kódu (např. malware)
- Reverzní inženýrství, zkoumání algoritmů a optimalizací v cizím kódu
- Výhody:
- Umožňuje získat vhled do chování strojového kódu nebo spustitelného souboru v čitelnější formě
- Pomáhá při analýze a ladění programů
- Nevýhody:
- Získaný zdrojový kód může být méně čitelný a komplexnější než původní zdrojový kód
- Ztráta informace o původních názvech proměnných, funkcí a komentářích
- Může být omezen na konkrétní programovací jazyk, architekturu nebo operační systém
Globální a lokální bezpečný bod (Global and Local Safe Point):
- Koncept používaný v runtime systémech, např. Java Virtual Machine (JVM)
- Bezpečný bod je místo v kódu, kde se runtime prostředí může přesvědčit, že žádné nebezpečné operace nebudou probíhat (např. úpravy objektů v paměti)
- Umožňuje provádět akce, které vyžadují kooperaci mezi vlákny nebo synchronizaci s garbage collectorem
Globální bezpečný bod (Global Safe Point):
- Všechna vlákna v runtime prostředí jsou pozastavena na bezpečných bodech
- Často využíván při stop-the-world fázi garbage collectoru
- Výhody:
- Zjednodušuje garbage collection, protože nedochází k současným úpravám objektů
- Umožňuje provádět operace s globálním dopadem na runtime prostředí
- Nevýhody:
- Způsobuje přerušení všech vláken, což může způsobit zpoždění a snížení výkonu aplikace
Lokální bezpečný bod (Local Safe Point):
- Vlákno dosáhne bezpečného bodu nezávisle na ostatních vláknech
- Používá se pro akce, které vyžadují kooperaci mezi vlákny, ale nepotřebují zastavit všechna vlákna
- Výhody:
- Méně náročné na výkon než globální bezpečný bod, protože nepozastavuje všechna vlákna
- Umožňuje provádět operace s lokálním dopadem na runtime prostředí
- Nevýhody:
- Může být složitější koordinovat akce mezi vlákny
- Méně vhodné pro operace s globálním dopadem na runtime prostředí
Čas do bezpečného bodu (Time to Safe Point):
- Metrika používaná pro měření doby, kterou trvá jednotlivým vláknům dosáhnout bezpečného bodu v runtime prostředí, např. Java Virtual Machine (JVM)
- Důležitá pro koordinaci akcí mezi vlákny a při garbage collection
- Měří časovou prodlevu mezi rozhodnutím o zastavení vláken na bezpečných bodech a skutečným dosažením těchto bodů
Faktory ovlivňující čas do bezpečného bodu:
- Délka části kódu mezi bezpečnými body
- Výkon a zátěž vláken
- Frekvence volání bezpečných bodů v kódu
- Implementace a nastavení runtime prostředí
Význam času do bezpečného bodu:
- Krátký čas do bezpečného bodu zvyšuje pružnost runtime prostředí a umožňuje rychlejší koordinaci mezi vlákny a garbage collectorem
- Dlouhý čas do bezpečného bodu může způsobit zpoždění a snížení výkonu aplikace, protože vlákna nemohou být rychle zastavena pro kooperaci s garbage collectorem nebo pro jiné akce vyžadující koordinaci mezi vlákny
- Optimalizace kódu a runtime prostředí mohou pomoci snížit čas do bezpečného bodu, např. zvyšováním frekvence volání bezpečných bodů nebo zlepšením implementace bezpečných bodů
Automatické správa paměti (Automatic Memory Management):
- Koncept, který se používá v programovacích jazycích a runtime prostředích, kde je paměťová správa automaticky řízena systémem, např. Java Virtual Machine (JVM)
- Hlavní součástí automatické správy paměti je garbage collector
Funkce automatické správy paměti: - Alokace paměti: Přidělení paměti pro nové objekty a proměnné - Uvolňování paměti: Systém automaticky detekuje a uvolňuje paměť, která již není potřeba (nepoužívané objekty) - Minimalizace úniku paměti a fragmentace: Garbage collector se snaží minimalizovat úniky paměti a její fragmentaci
Výhody automatické správy paměti: - Zjednodušuje programování, protože se programátor nemusí starat o přidělování a uvolňování paměti - Snížení chyb spojených s paměťovou správou, jako jsou úniky paměti nebo přístup k nealokované paměti - Zvyšuje bezpečnost a stabilitu aplikace, protože garbage collector detekuje a řeší problémy s paměťovou správou
Nevýhody automatické správy paměti: - Vyšší režie a zátěž systému kvůli garbage collectoru a automatickému přidělování/uvolňování paměti - Menší kontrola nad správou paměti, což může vést k suboptimálnímu výkonu aplikace v některých případech - Předvídatelnost a výkon garbage collectoru závisí na implementaci a konfiguraci runtime prostředí
Generační hypotéza (Generational Hypothesis):
- Teorie, která se používá při návrhu a implementaci garbage collectorů v automatických správách paměti, jako je Java Virtual Machine (JVM)
- Hypotéza předpokládá, že většina objektů v paměti má krátkou životnost, zatímco jen malé procento objektů má dlouhou životnost
Principy generační hypotézy:
- Mnoho objektů zemře mladých: Většina objektů má krátkou životnost a je rychle zničena
- Málo starých objektů odkazuje na mladé: Méně často dochází k odkazům mezi starými a mladými objekty
- Málo objektů přežije dlouhou dobu: Jen malé procento objektů má dlouhou životnost
Aplikace generační hypotézy na garbage collectory:
- Garbage collectory využívají generační hypotézu pro optimalizaci paměťové správy
- Paměť je rozdělena na dvě nebo více generací, např. “new generation” (mladá generace) a “old generation” (stará generace)
- Mladá generace obsahuje nově vytvořené objekty, které mají tendenci rychle zaniknout
- Stará generace obsahuje objekty, které přežily několik cyklů garbage collection a mají tendenci mít delší životnost
- Garbage collector se zaměřuje na mladou generaci, kde často probíhá uvolňování paměti, a méně často na starou generaci
Výhody použití generační hypotézy:
- Zlepšuje výkon garbage collectoru, protože se zaměřuje na části paměti, kde je největší pravděpodobnost uvolnění paměti
- Snížení režie a zátěže systému spojené s garbage collection
- Minimalizace zpoždění a přerušení způsobených garbage collection
Nevýhody použití generační hypotézy:
- Vyšší složitost implementace garbage collectoru
- Možná suboptimální výkon v případech, kdy hypotéza neodpovídá skutečnému chování aplikace
Garbage Collectory:
- Součást automatické správy paměti v runtime prostředích, jako je Java Virtual Machine (JVM)
- Starají se o automatické uvolňování paměti, která již není používána (nepotřebné objekty)
- Zajišťují, že aplikace nevyčerpá dostupnou paměť a snižují riziko úniků paměti
Některé typy garbage collectorů:
- Mark and Sweep (Označit a Zamést):
- Pracuje ve dvou fázích:
- Označení: Prochází živé objekty a označuje je jako dosažitelné
- Zametání: Uvolňuje paměť obsazenou objekty, které nebyly označeny jako dosažitelné
- Nevýhody: Může způsobovat fragmentaci paměti a zpoždění při provádění garbage collection
- Pracuje ve dvou fázích:
- Copying (Kopírování):
- Paměť je rozdělena na dvě poloviny: Aktivní a rezervní
- Živé objekty jsou kopírovány z aktivní do rezervní paměti
- Jakmile jsou všechny živé objekty kopírovány, celá aktivní paměť je uvolněna
- Nevýhody: Vyžaduje více paměti, protože je rozdělena na dvě části, a může způsobit zpoždění při provádění garbage collection
- Generational (Generační):
- Paměť je rozdělena na mladou a starou generaci
- Využívá generační hypotézu pro efektivnější garbage collection
- Častěji provádí garbage collection v mladé generaci, kde je vyšší pravděpodobnost uvolnění paměti
- Výhody: Snížení režie a zátěže systému, minimalizace zpoždění způsobených garbage collection
- Nevýhody: Vyšší složitost implementace
- Concurrent (Souběžný):
- Provádí garbage collection současně s během aplikace, bez nutnosti zastavit všechna vlákna
- Výhody: Snížení zpoždění a přerušení způsobených garbage collection, lepší výkon aplikace
- Nevýhody: Vyšší složitost implementace a koordinace s běžícími vlákny
- Incremental (Inkrementální):
- Rozděluje garbage collection do menších částí, které jsou prováděny postupně
- Výhody: Snížení zpoždění a přerušení způsoben
CPU a paměťový profiling:
- Techniky používané pro analýzu výkonu a chování aplikace s ohledem na zpracování CPU a využití paměti
- Cílem je identifikovat horké body (bottlenecks), optimalizovat výkon a zlepšit paměťovou efektivitu aplikace
CPU profiling: - Zaměřuje se na měření a analýzu výkonu aplikace v souvislosti s využitím procesoru - Identifikuje funkce a části kódu, které vyžadují nejvíce času na zpracování - Pomáhá zjistit, kde lze provést optimalizace kódu pro zlepšení celkového výkonu aplikace
Metody CPU profilingu: 1. Sampling (vzorkování): Pravidelně sbírá informace o zásobníku volání (call stack) během běhu aplikace 2. Instrumentace: Vkládá sledovací kód přímo do aplikace, který zaznamenává informace o výkonu a zátěži CPU
Paměťový profiling: - Zaměřuje se na analýzu využití paměti aplikací - Identifikuje objekty, které způsobují zvýšené využití paměti, úniky paměti nebo fragmentaci paměti - Pomáhá zjistit, jak lze zlepšit paměťovou efektivitu a snížit nároky na paměť aplikace
Metody paměťového profilingu: 1. Heap snapshot (snímek haldy): Zaznamenává stav paměti (haldy) v určitém čase, identifikuje objekty a jejich velikosti 2. Allocation tracking (sledování alokace): Sleduje vytváření a uvolňování objektů v paměti během běhu aplikace 3. Garbage collection profiling: Analyzuje chování garbage collectoru, identifikuje dlouhotrvající operace a možné optimalizace
Nástroje pro CPU a paměťový profiling: - Existuje mnoho nástrojů a knihoven pro různé jazyky a prostředí, například: - VisualVM (pro Java) - Valgrind (pro C/C++) - Py-Spy (pro Python) - Ruby-prof (pro Ruby)
Vzorkování (Sampling) a trasování (Tracing) přístup:
- Dvě hlavní metody používané při profilování výkonu aplikací, zejména v souvislosti s CPU a paměťovým profilingem
Vzorkování (Sampling):
- Pravidelně sbírá informace o zásobníku volání (call stack) během běhu aplikace
- Zkoumá výkon aplikace v pravidelných intervalech a zaznamenává aktuální stav
- Menší režie než u trasování, protože se nezasahuje do každé funkce nebo události
- Méně přesné než trasování, protože data jsou založena na vzorcích a mohou být ovlivněna časováním nebo frekvencí vzorkování
Trasování (Tracing):
- Vkládá sledovací kód přímo do aplikace, který zaznamenává informace o výkonu a zátěži
- Sleduje všechny funkce, události a interakce v aplikaci, což poskytuje detailní informace o výkonu
- Vyšší režie než u vzorkování, protože se zaznamenává každá funkce a událost
- Přesnější než vzorkování, protože data jsou založena na skutečném chování aplikace, nikoli na vzorcích
Kdy použít vzorkování nebo trasování:
- Vzorkování je vhodné pro rychlou a hrubou analýzu výkonu aplikace, kde je důležitější minimalizace režie než přesnost dat
- Trasování je vhodné pro detailní a přesnou analýzu výkonu aplikace, kde je důležitější získat kompletní informace o chování aplikace než minimalizovat režii
- Ve většině případů je vhodné použít kombinaci obou přístupů pro dosažení nejlepších výsledků při analýze výkonu aplikace
Fáze rozehřátí (Warm-up phase):
- Období, kdy se aplikace nebo systém rozehřívá a dosahuje optimálního výkonu
- Během fáze rozehřátí může aplikace nebo systém provádět různé inicializační úkoly, kompilaci, optimalizace nebo jiné nastavení
- Výkon aplikace nebo systému během fáze rozehřátí může být pomalejší než po dosažení optimálního výkonu
Důvody pro fázi rozehřátí: 1. Just-In-Time (JIT) kompilace: Aplikace založené na bytecode, jako je Java, používají JIT kompilátor pro kompilaci bytecode na strojový kód během runtime. Tato kompilace může trvat určitý čas a zpočátku zpomalit výkon. 2. Profilování a optimalizace: Aplikace nebo systém mohou provádět profilování a optimalizace během fáze rozehřátí, což může způsobit zpoždění v dosažení plného výkonu. 3. Cache a přednačítání: Aplikace mohou mít cache nebo přednačítání dat, které mohou být potřeba pro rychlejší běh. Tyto cache nebo přednačítaná data se mohou postupně naplňovat během fáze rozehřátí.
Jak zohlednit fázi rozehřátí při testování výkonu: - Během testování výkonu je důležité zohlednit fázi rozehřátí, protože může ovlivnit výsledky testů - Testy by měly být prováděny po dosažení optimálního výkonu aplikace nebo systému, aby poskytovaly správné a relevantní výsledky - Mohou být použity různé techniky pro zohlednění fáze rozehřátí, například: - Provedení několika krátkých běhů aplikace nebo testů před spuštěním hlavního testu - Použití statistických metod pro eliminaci nebo minimalizaci vlivu fáze rozehřátí na výsledky testů
Data race (soupeření o data):
- Problém v paralelním programování, kdy dojde ke konkurenčnímu přístupu dvou nebo více vláken k témuž datovému objektu bez vhodné synchronizace
- Může vést k nekonzistentním a nepředvídatelným výsledkům, což ztěžuje ladění a opravu chyb
- Nejčastěji se vyskytuje v programovacích jazycích, které umožňují ruční správu vláken a synchronizaci, jako jsou C++, Java nebo C#
Příčiny data race: 1. Neexistující nebo nesprávná synchronizace přístupu k datům 2. Chybějící zámky (locks) nebo bariéry (barriers) pro omezení přístupu k datům 3. Nesprávná implementace atomických operací nebo kritických sekcí
Jak předcházet data race: 1. Použití zámků (locks) pro zajištění vzájemného vyloučení při přístupu k datům 2. Využití atomických operací, které zajišťují, že během provedení operace nedojde k přerušení vlákny 3. Použití bariér (barriers) nebo podmínek (conditions) pro koordinaci a synchronizaci vláken 4. Vhodná dekompozice úloh a dat pro snížení potřeby sdílení dat mezi vlákny 5. Použití vysokoúrovňových abstrakcí a knihoven pro paralelní programování, které řeší synchronizaci za vás (např. OpenMP, TBB, C++11 threads)
Detekce data race: - Existují nástroje a techniky pro automatickou detekci data race, například: - Statická analýza kódu: Nástroje jako Clang Static Analyzer nebo PVS-Studio mohou pomoci identifikovat možné data race v kódu - Dynamická analýza běhu: Nástroje jako Helgrind (součást Valgrind), ThreadSanitizer nebo Intel Inspector mohou sledovat běh aplikace a detekovat data race za běhu
CPU pipelining (potrubí) a superskalární architektura:
CPU pipelining (potrubí):
- Technika zvyšování výkonu procesoru tím, že se zpracování instrukcí rozdělí do několika menších kroků (fází)
- Každá fáze zpracovává část instrukce a poté ji předává další fázi
- Umožňuje paralelní zpracování více instrukcí, kdy každá instrukce prochází jednotlivými fázemi potrubí
Superskalární architektura:
- Rozšíření pipeliningu, které umožňuje zpracovávat více instrukcí současně v rámci jednoho cyklu hodinových tiků
- Superskalární procesory mají více výkonných jednotek, které mohou zpracovávat instrukce paralelně
- Díky této architektuře je možné dosáhnout vyššího výkonu a rychlejšího zpracování instrukcí než u tradičních pipelined procesorů
Kombinace CPU pipeliningu a superskalární architektury:
- Instrukce jsou načítány do potrubí a rozděleny do menších kroků (fází)
- Procesor s superskalární architekturou může zpracovávat více instrukcí současně v rámci jednoho cyklu hodinových tiků
- Výsledkem je vyšší výkon a rychlejší zpracování instrukcí
Příklady procesorů s pipeliningem a superskalární architekturou:
- Většina moderních procesorů (Intel Core, AMD Ryzen) používá kombinaci pipeliningu a superskalární architektury pro dosažení vysokého výkonu
Paměťová bariéra (Memory barrier):
- Mechanismus v paralelním programování, který zajišťuje správné pořadí přístupu k paměti mezi různými vlákny nebo procesory
- Pomáhá předcházet problémům se souběžností, jako jsou data race nebo nekonzistence paměti
- Paměťové bariéry mohou být implementovány na úrovni hardware (CPU instrukce) nebo software (programovací jazyk, knihovny)
Účel paměťových bariér:
- Zajištění, že zápis nebo čtení určitých dat je dokončeno před pokračováním dalších operací
- Zajištění, že změny v paměti provedené jedním vláknem nebo procesorem jsou viditelné pro ostatní vlákna nebo procesory
- Zajištění, že operace na sdílených datech jsou prováděny ve správném pořadí
Příklady paměťových bariér:
- V jazyce C++ mohou být použity atomické operace s různými paměťovými řády (memory_order) pro zajištění správného pořadí přístupu k paměti
- V jazyce Java mohou být použity synchronizované bloky nebo volatile proměnné pro zajištění správného pořadí přístupu k paměti
- Některé CPU instrukce, jako je mfence, sfence a lfence na platformě x86, poskytují paměťové bariéry na úrovni hardware
Použití paměťových bariér:
- Paměťové bariéry by měly být použity v situacích, kdy je důležité zajistit správné pořadí přístupu k paměti mezi vlákny nebo procesory
- Správné použití paměťových bariér může pomoci předcházet problémům s nekonzistencí paměti a data race, ale může také způsobit pokles výkonu
- Je důležité pečlivě zvážit potřebu paměťových bariér a použít je jen tam, kde je to nezbytné, aby se minimalizoval vliv na výkon
Volatile proměnná:
- Klíčové slovo
volatilev programovacích jazycích (jako C, C++ nebo Java) označuje proměnnou, která může být změněna vnějšími procesy nebo paralelními vlákny - Při použití
volatilekompilátor a běhové prostředí zajišťují, že přístupy k této proměnné nebudou optimalizovány ani mezipaměťovány, což zajišťuje konzistentní a aktuální hodnoty pro všechna vlákna
Java
volatilev Javě se používá pro označení proměnné, jejíž hodnota může být modifikována více vlákny a jejíž přístupy by neměly být optimalizovány.- Klíčové vlastnosti:
- Viditelnost: Čtení a zápis proměnné označené jako
volatilejsou zaručeně viditelné pro ostatní vlákna. - Pořadí: Ustanovuje vzájemný vztah happens-before, což zajišťuje, že
akce před zápisem do
volatileproměnné se provedou před následujícími akcemi po jejím čtení. - Atomické R/W operace
- Viditelnost: Čtení a zápis proměnné označené jako
- Použití:
- Jednoduché příznakové proměnné sdílené mezi více vlákny.
- Koordinace mezi vlákny pomocí sdílené proměnné.
- Omezení:
- Neposkytuje atomicitu pro složené operace.
- Omezené synchronizační schopnosti ve srovnání s
synchronizedbloky, zámky nebo atomickými třídami.
C++
- Klíčové slovo
volatilev C++ označuje, že hodnota proměnné se může kdykoliv změnit bez vědomí kompilátoru, často z důvodu externích faktorů. - Klíčové vlastnosti:
- Čtení/Zápis volatile: Přikazuje kompilátoru vždy číst a zapisovat do paměti pro danou proměnnou, aniž by se spoléhal na mezipaměťové hodnoty.
- Externí modifikace: Označuje, že proměnnou mohou měnit externí faktory, jako je hardware nebo jiná vlákna.
- Použití:
- Přístup k registrům hardware připojených k paměti.
- Vícevláknové prostředí, kde více vláken přistupuje ke stejné proměnné.
- Omezení:
- Samotné
volatileneposkytuje záruky synchronizace nebo atomicity. - Pro synchronizaci a viditelnost napříč více jádry nebo vlákny je nutné použít vhodné synchronizační mechanismy, jako jsou mutexy, atomické typy nebo bariéry paměti.
- Samotné
Synchronizace - tenké (thin), tlusté (fat) a zaujaté (biased) zámky:
Tenký zámek (Thin lock):
- Lehký zámek s nízkým režijním zatížením, používaný v situacích, kdy není vysoká kontestace mezi vlákny
- Rychlý a efektivní způsob zajištění synchronizace pro jednoduché případy
- V případě zvýšené kontestace mezi vlákny může být tenký zámek transformován na tlustý zámek
Tlustý zámek (Fat lock):
- Robustnější zámek s vyšším režijním zatížením, používaný v situacích, kdy je vysoká kontestace mezi vlákny
- Poskytuje lepší výkon při zajištění synchronizace v případě, že se více vláken soupeří o přístup ke sdíleným zdrojům
- Transformace z tenkého zámku na tlustý zámok probíhá za běhu, pokud je to nutné
Zaujatý zámek (Biased locking):
- Optimalizace zámku, která zvyšuje výkon synchronizace v situacích, kdy objekt používá jedno vlákno a ostatní vlákna se o něj nezajímají
- Zámek je “zaujatý” ve prospěch jednoho vlákna, které může provádět synchronizované operace bez nutnosti získávání zámku
- Pokud se objekt stane kontestovaným mezi více vlákny, zaujatý zámek může být zrušen a převeden na tenký nebo tlustý zámek
Reentrant zámky:
- Typ synchronizačního mechanismu, který umožňuje vláknu získat zámek vícekrát, aniž by došlo k uváznutí (deadlock)
- Reentrant zámek sleduje, které vlákno drží zámek a kolikrát ho získalo
- Vlákno může opustit zámek pouze tehdy, pokud uvolní zámek stejný počet, kolikrát ho získalo
Vlastnosti reentrant zámků:
- Povolují vnořené zamykání (nested locking), což umožňuje vláknu získat zámek vícekrát, aniž by došlo k uváznutí
- Zvyšují robustnost kódu tím, že se zabrání uváznutí při opakovaném získání zámku stejným vláknem
- Mohou poskytnout pokročilé funkce, jako je podpora přerušitelného zamykání, časově omezené zamykání nebo spravedlivé plánování
import java.util.concurrent.locks.ReentrantLock;
ReentrantLock lock = new ReentrantLock();
// Získání zámku
lock.lock();
try {
// kritická sekce
} finally {
// Uvolnění zámku
lock.unlock();
}#include <mutex>
std::recursive_mutex mtx;
// Získání zámku
mtx.lock();
try {
// kritická sekce
} catch (...) {
// Uvolnění zámku
mtx.unlock();
throw;
}
// Uvolnění zámku
mtx.unlock();Atomické operace založené na instrukcích porovnat-a-nastavit (compare-and-set):
- Atomické operace, které kombinují porovnání a nastavení hodnoty v jediném nesdíleném (atomic) kroku
- Běžně používány pro implementaci bezpečných a efektivních synchronizačních mechanismů, jako jsou zámky, semafory nebo počítadla
- Základem pro mnoho lock-free a wait-free algoritmů, které umožňují vysoký výkon a škálovatelnost v paralelním prostředí
Princip compare-and-set (CAS) operace:
- Porovnej hodnotu sdílené proměnné s očekávanou hodnotou
- Pokud se hodnoty shodují, nastav novou hodnotu proměnné
- Operace vrátí informaci, zda byla hodnota úspěšně nastavena nebo ne
Výhody compare-and-set operací:
- Poskytují atomičnost a zajišťují konzistenci dat při přístupu více vláken
- Mohou snižovat režijní zatížení v porovnání s tradičními zámky nebo synchronizačními mechanismy
- Umožňují vytvářet lock-free a wait-free algoritmy, které jsou škálovatelné a odolné vůči uváznutí (deadlock) a vyhladovění (starvation)
Atomické aktualizátory polí (Atomic Field Updaters):
- Specializované utility pro atomické aktualizace polí objektů bez nutnosti vytvářet nové objekty s atomickými proměnnými
- Umožňují provádět operace na jednotlivých polích objektů, které jsou atomické a bezpečné při současném přístupu více vláken
- Zvyšují výkon a snižují režijní zatížení v paralelním prostředí díky snížení počtu vytvořených objektů
Výhody atomických aktualizátorů polí:
- Poskytují atomičnost a zajišťují konzistenci dat při přístupu více vláken k jednotlivým polím objektů
- Snížení režijního zatížení a zlepšení výkonu v paralelním prostředí díky menšímu počtu vytvořených objektů
- Umožňují vytvářet lock-free a wait-free algoritmy pro práci s objekty
Použití atomických aktualizátorů polí:
- V jazyce Java lze použít třídy
AtomicIntegerFieldUpdater,AtomicLongFieldUpdateraAtomicReferenceFieldUpdaterz balíčkujava.util.concurrent.atomic - Pro jejich použití je nutné definovat pole objektu jako
volatile
Neblokující algoritmy (Non-blocking algorithms):
- Typ algoritmů, které nezabraňují přístupu k sdíleným datům nebo zdrojům jiným vláknům, když je prováděna operace
- Zajišťují, že žádné vlákno nebude čekat na neomezeně dlouhou dobu na dokončení operace prováděné jiným vláknem
- Mohou být klasifikovány jako lock-free, wait-free nebo obstruction-free, v závislosti na garancích, které poskytují
Typy neblokujících algoritmů:
- Lock-free algoritmy:
- Zajišťují, že alespoň jedno vlákno dokončí svou operaci v konečném čase
- Zabraňují uváznutí (deadlocks) a vyhladovění (starvation)
- Wait-free algoritmy:
- Poskytují garanci, že každé vlákno dokončí svou operaci v konečném čase
- Zabraňují uváznutí, vyhladovění a čekání na dokončení jiných vláken
- Obstruction-free algoritmy:
- Poskytují garanci, že operace bude dokončena v konečném čase pouze v případě, že žádné jiné vlákno nezasahuje do provádění operace
- Slabší záruky než lock-free a wait-free algoritmy, ale stále zabraňují uváznutí
Výhody neblokujících algoritmů:
- Vysoký výkon a škálovatelnost v paralelním prostředí
- Zabraňují uváznutí a vyhladovění, které mohou nastat při použití tradičních zámků a synchronizačních mechanismů
- Zvyšují robustnost a spolehlivost paralelního kódu díky snížení možnosti uváznutí a vyhladovění
Wait-free algoritmy:
- Speciální třída neblokujících algoritmů, které poskytují nejlepší záruky konvergence pro současně běžící vlákna
- Zajišťují, že každé vlákno dokončí svou operaci v konečném čase bez ohledu na chování ostatních vláken
- Zabraňují problémům, jako je uváznutí (deadlock), vyhladovění (starvation) a zbytečné čekání na dokončení jiných vláken
Vlastnosti wait-free algoritmů: 1. Konečná konvergence: Každé vlákno dokončí svou operaci v konečném čase, bez ohledu na ostatní vlákna 2. Robustnost: Odpovědnost za dokončení operace leží na provádějícím vlákně, což zabraňuje závislosti na chování jiných vláken 3. Spravedlivost: Žádné vlákno nemůže být trvale blokováno jiným vláknem, což zabraňuje vyhladovění
Výhody wait-free algoritmů: - Vysoká škálovatelnost a výkon v paralelním prostředí - Zlepšení spolehlivosti a robustnosti paralelního kódu díky odstranění závislosti na chování jiných vláken - Poskytují nejlepší záruky konvergence ze všech typů neblokujících algoritmů
Příklady wait-free algoritmů: - Wait-free fronty, zásobníky nebo počítadla, které zajišťují spravedlivý přístup ke sdíleným datovým strukturám - Wait-free implementace atomických proměnných nebo operací, jako jsou compare-and-set nebo fetch-and-add
Použití wait-free algoritmů může být složitější než použití lock-free nebo obstruction-free algoritmů, ale poskytuje nejlepší záruky pro paralelní výpočty.
Neblokující zásobník (LIFO) - Non-blocking Stack:
- Zásobník implementovaný jako neblokující datová struktura, která umožňuje současný přístup více vláken bez nutnosti použití zámků nebo synchronizačních mechanismů
- Používá atomické operace, jako jsou compare-and-set (CAS), pro zajištění konzistence a bezpečnosti dat při současném přístupu více vláken
- Zabraňuje problémům, jako je uváznutí (deadlock) a vyhladovění (starvation), které mohou nastat při použití tradičních zámků a synchronizačních mechanismů
Základní operace nebokujícího zásobníku (LIFO):
- Push: Přidání prvku na vrchol zásobníku
- Pop: Odebrání prvku z vrcholu zásobníku
Implementace nebokujícího zásobníku (LIFO):
- Základem implementace je spojový seznam s hlavou (head), která ukazuje na vrchol zásobníku
- Pro operaci Push a Pop se používá compare-and-set (CAS) operace, která zajišťuje atomičnost a konzistenci dat při přístupu více vláken
- V případě, že CAS operace selže, vlákno opakuje operaci, dokud není úspěšná
Výhody nebokujícího zásobníku (LIFO):
- Vysoký výkon a škálovatelnost v paralelním prostředí díky snížení režijního zatížení spojeného se zámky a synchronizací
- Zabraňuje uváznutí (deadlock) a vyhladovění (starvation), které mohou nastat při použití tradičních zámků a synchronizačních mechanismů
- Zvyšuje robustnost a spolehlivost paralelního kódu díky odstranění možnosti uváznutí a vyhladovění
Statická a dynamická analýza paměti:
Statická analýza paměti:
- Provádí kontrolu zdrojového kódu bez jeho spuštění
- Identifikuje potenciální problémy s pamětí, jako jsou úniky paměti (memory leaks), neinicializované proměnné nebo nesprávné uvolňování paměti
- Zahrnuje kontrolu správnosti kódu, hledání nebezpečných funkcí nebo analýzu toku dat
- Pomáhá odhalit chyby a zlepšit kvalitu kódu před jeho spuštěním
Dynamická analýza paměti:
- Provádí kontrolu během provádění programu, monitoruje jeho chování a alokaci paměti
- Identifikuje problémy s pamětí v reálném čase, jako jsou úniky paměti, přístupy mimo rozsah pole nebo nesprávné uvolňování paměti
- Vyžaduje spuštění programu a sledování jeho chování, což může způsobit zpomalení běhu
- Umožňuje zjistit chyby, které nebyly odhaleny statickou analýzou, a poskytuje detailnější informace o problémech s pamětí
Výhody statické a dynamické analýzy paměti:
- Odhalení chyb, úniků paměti a problémů s pamětí, které mohou vést k nestabilitě nebo zranitelnostem v aplikaci
- Zlepšení kvality kódu a výkonu programu díky efektivnímu řešení problémů s pamětí
- Umožňuje vývojářům zaměřit se na kritické problémy a snížit riziko chyb ve výsledné aplikaci
Mělká velikost (Shallow size) a zadržená velikost (Retained size):
Mělká velikost (Shallow size): - Velikost paměti, kterou přímo zabírá objekt, bez zahrnutí paměti zabírané objekty, na které odkazuje - Zahrnuje pouze velikost objektu a jeho přímých atributů, nikoli objektů, které jsou dostupné prostřednictvím referencí - Mělká velikost objektu je konstantní pro objekty stejného typu, protože závisí pouze na počtu atributů a jejich typu
Zadržená velikost (Retained size): - Celková velikost paměti, kterou zabírá objekt a všechny objekty, které jsou dostupné pouze prostřednictvím tohoto objektu - Zahrnuje velikost objektu a všechny jeho tranzitivně dostupné objekty prostřednictvím referencí - Pokud by byl tento objekt uvolněn, zadržená velikost ukazuje, kolik paměti by bylo uvolněno
Význam mělké a zadržené velikosti při analýze paměti: - Pomáhají identifikovat úniky paměti (memory leaks) a nadměrné využití paměti v aplikacích - Umožňují vývojářům zjistit, které objekty nebo části kódu nejvíce přispívají k celkovému využití paměti - Poskytují informace, které mohou vést k optimalizaci kódu a efektivnějšímu využití paměti
Únik paměti (Memory leak):
- Problém, když program nepřestává alokovat paměť, aniž by ji následně správně uvolnil, což vede ke zvýšenému využití paměti
- Může vést k degradaci výkonu, nestabilitě nebo selhání aplikace
- Často způsoben chybami v kódu, kdy programátor zapomene uvolnit alokovanou paměť nebo se objeví cyklické reference, které brání automatickému uvolňování paměti (např. v jazyce Java s garbage collectorem)
Příčiny úniků paměti: 1. Nesprávné uvolňování paměti: Programátor alokuje paměť, ale zapomene ji uvolnit 2. Cyklické reference: Dva nebo více objektů si navzájem udržují reference, což brání jejich automatickému uvolnění 3. Statické proměnné: Proměnné, které zůstávají v paměti po celou dobu běhu programu, a které mohou neúmyslně udržovat reference na objekty
Detekce a řešení úniků paměti:
- Použití nástrojů pro statickou a dynamickou analýzu paměti k identifikaci potenciálních úniků paměti a zlepšení kvality kódu
- Revize kódu, aby se zajistilo správné uvolňování paměti a předešlo se cyklickým referencím
- V případě jazyků s garbage collectorem je důležité porozumět jeho chování a mechanismům uvolňování paměti, aby se předešlo neúmyslným únikům paměti
Datové struktury
- Způsob organizace, správy a ukládání dat, který umožňuje efektivní přístup a modifikaci dat
- Každá datová struktura má své vlastnosti a využití, které ji činí vhodnou pro konkrétní typ úlohy
- Základní datové struktury zahrnují pole, spojové seznamy, zásobníky, fronty, stromy a grafy
- Pole (Array):
- Statická datová struktura s pevnou velikostí
- Umožňuje rychlý přístup k prvku na základě indexu
- Nevýhoda: neměnná velikost, která může vést k neefektivnímu využití paměti
- Spojový seznam (Linked list):
- Dynamická datová struktura, která se skládá z uzlů obsahujících data a odkaz na další uzel v seznamu
- Umožňuje snadné vkládání a mazání prvků bez nutnosti přesunu ostatních prvků
- Nevýhoda: pomalejší přístup k prvkům, protože je nutné projít seznam od začátku
- Zásobník (Stack):
- Lineární datová struktura, která pracuje na principu LIFO (Last In, First Out)
- Umožňuje přidávání a odebírání prvků pouze z vrcholu zásobníku
- Vhodné pro úlohy, které vyžadují rekurzi nebo zpětné sledování (backtracking)
- Fronta (Queue):
- Lineární datová struktura, která pracuje na principu FIFO (First In, First Out)
- Umožňuje přidávání prvků na konec fronty a odebírání z jejího začátku
- Vhodné pro úlohy, které vyžadují sekvenční zpracování dat
- Strom (Tree):
- Hierarchická datová struktura, která se skládá z uzlů propojených hranami
- Umožňuje efektivní vyhledávání, vkládání a mazání prvků v závislosti na konkrétním typu stromu (binární strom, AVL strom, B-strom, atd.)
- Vhodné pro úlohy, které vyžadují hierarchickou organizaci dat
- Graf (Graph):
- Datová struktura, která se skládá z uzlů (vrcholů) a hran mezi nimi
- Umožňuje reprezentovat složité vztahy mezi objekty
- Vhodné pro
Java primitivní typy a objekty:
Primitivní typy:
- Základní datové typy přímo zabudované do jazyka Java
- Zahrnují celá čísla, desetinná čísla, znaky a logické hodnoty
- Ukládány na zásobníku (stack) a předávány hodnotou
- Primitivní typy v Javě zahrnují:
byte,short,int,long,float,double,char,boolean
Objekty:
- Instance tříd definovaných v Javě nebo vlastních tříd vytvořených programátorem
- Ukládány na haldě (heap) a předávány referencí
- Objekty zahrnují všechny neprimitivní datové typy, jako jsou třídy,
pole, kolekce a také tzv. “wrapper” třídy pro primitivní typy (např.
Integer,Double,Character,Boolean) - Každý objekt je implicitně odvozen od třídy
Object, která poskytuje základní metody pro všechny objekty
Rozdíly mezi primitivními typy a objekty: 1. Ukládání: Primitivní
typy jsou ukládány na zásobníku, zatímco objekty na haldě 2. Předávání:
Primitivní typy jsou předávány hodnotou, objekty referencí 3. Výchozí
hodnoty: Primitivní typy mají výchozí hodnoty (např. 0 pro
int, false pro boolean), zatímco
objekty mají výchozí hodnotu null 4. Metody: Objekty mohou
mít metody a být součástí dědičnosti, primitivní typy nemají metody ani
dědičnost 5. Wrapper třídy: Pro každý primitivní typ existuje “wrapper”
třída, která umožňuje pracovat s primitivním typem jako s objektem
(např. Integer pro int, Double
pro double)
Auto-boxing a unboxing:
Auto-boxing:
- Automatický proces převodu primitivního typu na jeho odpovídající “wrapper” třídu (objektový typ)
- Java kompilátor provádí auto-boxing implicitně, když je to nutné
- Příklad: Přiřazení primitivního typu
intdo objektového typuInteger
Unboxing:
- Automatický proces převodu “wrapper” třídy (objektového typu) na její odpovídající primitivní typ
- Java kompilátor provádí unboxing implicitně, když je to nutné
- Příklad: Přiřazení objektového typu
Integerdo primitivního typuint
Efektivita paměti složitých datových struktur:
Efektivita paměti datových struktur závisí na:
- Režii paměti: Každá datová struktura vyžaduje určité množství paměti pro uložení dodatečných informací, jako jsou odkazy, ukazatele nebo metadata.
- Pevnosti velikosti: Některé datové struktury mají pevnou velikost, zatímco jiné mohou být dynamicky zvětšovány nebo zmenšovány podle potřeby.
- Vnitřní fragmentace: Vnitřní fragmentace nastává, když datová struktura má nevyužité části paměti, které nelze přiřadit jiným objektům.
Příklady efektivity paměti některých složitých datových struktur:
- Binární vyhledávací strom (Binary Search Tree):
- Efektivní v případě, že je strom vyvážený
- Má režii paměti z důvodu ukládání odkazů na levý a pravý potomek pro každý uzel
- Může mít neefektivní využití paměti, pokud je strom silně nevyvážený
- Hash tabulka (Hash Table):
- Má režii paměti pro ukládání ukazatelů na prvky a pro správu kolizí
- Při správně nastavené velikosti tabulky a vhodné hashovací funkci může být efektivní z hlediska paměti
- Vnitřní fragmentace nastává, když je velikost tabulky příliš velká nebo malá vzhledem k počtu prvků
- Grafová reprezentace (Graph Representation):
- Matice sousednosti: Má režii paměti kvůli ukládání celé matice, i když je graf řídký (má málo hran)
- Seznam sousednosti: Má menší režii paměti než matice sousednosti, ale vyžaduje ukládání odkazů na seznamy sousedů pro každý vrchol
- Efektivita paměti závisí na hustotě grafu a způsobu reprezentace
Optimalizace efektivity paměti:
- Výběr vhodné datové struktury pro konkrétní problém, která minimalizuje režii paměti a vnitřní fragmentaci
- V případě dynamických datových struktur správně nastavit velikost a strategii zvětšování/zmenšování, aby se minimalizovala fragmentace a režie paměti
- Použití kompresních technik pro snížení paměťových nároků, pokud je to vhodné (např. komprese trie stromu)
- Využití cache a paměťových návrhových vzorů pro zlepšení výkonu a efektivity paměti (např. LRU cache)
- Provést analýzu paměti a ladění, aby se identifikovaly a odstranily úniky paměti nebo neefektivní využití paměti
- Použití slabých referencí, soft referencí nebo phantom referencí pro zlepšení správy paměti a zamezení úniků paměti v Javě
- V případě, že je to možné, sdílet části dat mezi různými datovými strukturami nebo instancemi, aby se snížila režie paměti (např. internování řetězců v Javě)
Při návrhu a implementaci složitých datových struktur je důležité najít rovnováhu mezi efektivitou paměti, výkonem a čitelností kódu. Vybraná datová struktura by měla být vhodná pro konkrétní problém, snadno použitelná a rozšiřitelná a současně co nejméně náročná na paměť.
Kolekce pro výkon:
Výběr správné kolekce pro výkon závisí na požadavcích na časovou složitost a paměťovou efektivitu konkrétního problému. Některé běžné kolekce v Javě a jejich výkonnostní charakteristiky:
- ArrayList:
- Rychlý přístup k prvkům pomocí indexu (O(1))
- Pomalejší přidávání a odebírání prvků uprostřed seznamu (O(n))
- Dynamicky se zvětšuje, když je kapacita překročena
- LinkedList:
- Rychlé přidávání a odebírání prvků na začátku a konci seznamu (O(1))
- Pomalejší přístup k prvkům pomocí indexu (O(n))
- Vyšší režie paměti kvůli ukládání odkazů na předchozí a následující prvky
- HashSet:
- Rychlé přidávání, odebírání a vyhledávání prvků (průměrně O(1))
- Nepodporuje žádné pořadí prvků
- Vyšší režie paměti než ArrayList, ale nižší než LinkedList
- TreeSet:
- Rychlé přidávání, odebírání a vyhledávání prvků (O(log n))
- Udržuje prvky seřazené podle jejich přirozeného řazení nebo podle komparátoru
- Vyšší režie paměti než HashSet
- HashMap:
- Rychlý přístup, přidávání a odebírání klíč-hodnota párů (průměrně O(1))
- Nepodporuje žádné pořadí klíčů ani hodnot
- Vyšší režie paměti než ArrayList, ale nižší než LinkedList
- TreeMap:
- Rychlý přístup, přidávání a odebírání klíč-hodnota párů (O(log n))
- Udržuje klíče seřazené podle jejich přirozeného řazení nebo podle komparátoru
- Vyšší režie paměti než HashMap
Při výběru kolekce pro výkon zvažte následující faktory:
- Požadovaná časová složitost operací (přístup, přidávání, odebírání, vyhledávání)
- Pořadí prvků (potřeba udržovat prvky seřazené nebo ne)
- Paměťová efektivita (režie paměti a dynamické zvětšování/zmenšování)
- Podpora pro konkurenci a synchronizaci (např. ConcurrentHashMap pro bezpečné použití ve vícevláknovém prostředí)
Typově specifické kolekce:
Typově specifické kolekce jsou kolekce, které jsou navrženy pro ukládání primitivních datových typů nebo konkrétních tříd. Použití těchto kolekcí může zlepšit výkon a snížit režii paměti, protože se eliminuje potřeba autoboxingu a unboxingu.
Některé příklady typově specifických kolekcí:
- Trove knihovna (Java):
- Poskytuje kolekce pro primitivní typy, jako jsou TIntArrayList, TDoubleHashSet, TObjectIntHashMap atd.
- Nabízí nižší režii paměti a rychlejší operace než standardní Java kolekce
- FastUtil knihovna (Java):
- Poskytuje kolekce pro primitivní typy, jako jsou LongArrayList, Int2ObjectOpenHashMap, DoubleLinkedOpenHashSet atd.
- Nabízí nízkoúrovňové kolekce pro rychlý přístup a manipulaci s daty
- Rychlejší než standardní Java kolekce a podporuje vysokou kompresi dat
- Apache Commons Primitives (Java):
- Poskytuje kolekce pro primitivní typy, jako jsou IntList, DoubleStack, ObjectIntMap atd.
- Snadné použití a integrace se standardními Java kolekcemi
- Eclipse Collections (Java):
- Poskytuje kolekce pro primitivní typy i objekty, jako jsou IntArrayList, LongHashSet, MutableObjectIntMap atd.
- Bohatá API pro práci s daty a pokročilé funkce, jako jsou paralelní zpracování, lazy evaluace, atd.
- C++ Standard Template Library (STL):
- Poskytuje kolekce pro primitivní typy i třídy, jako jsou vector, list, set, map, atd.
- Přizpůsobitelné a rozšiřitelné pomocí šablon a vlastních komparátorů nebo alokátorů
Při výběru typově specifických kolekcí zvažte následující faktory:
- Výkon: Typově specifické kolekce mohou poskytnout rychlejší operace a nižší režii paměti než obecné kolekce
- Integrace: Zkontrolujte, jak snadno lze typově specifickou kolekci integrovat do vaší aplikace a jak dobře spolupracuje se standardními kolekcemi nebo knihovnami
- Kompatibilita: Ujistěte se, že typově specifická kolekce je kompatibilní s vaší verzí jazyka a platformy
- Podpora a údržba: Zvažte úroveň podpory a údržby pos
Otevřené adresování hashování:
Otevřené adresování hashování je metoda řešení kolizí v hash tabulkách, která nevyžaduje použití externích datových struktur (např. seznamů) pro ukládání prvků s kolizí. Místo toho jsou všechny prvky uloženy přímo v hash tabulce.
Klíčové vlastnosti otevřeného adresování hashování:
- Kolize řešeny prostřednictvím sekvenčního hledání volného místa v hash tabulce
- Různé metody pro hledání volného místa:
- Lineární sondování: Při kolizi se postupně prochází následující pozice, dokud není nalezeno volné místo
- Kvadratické sondování: Při kolizi se skáče na pozice s rostoucími kvadratickými intervaly, dokud není nalezeno volné místo
- Dvojité hashování: Při kolizi se použije druhá hashovací funkce pro určení intervalu skoků, dokud není nalezeno volné místo
- Prostorová efektivita: Otevřené adresování hashování může mít nižší režii paměti než hashování s řetězci, protože nevyžaduje externí datové struktury
- Výkon: Otevřené adresování hashování může být rychlejší než hashování s řetězci, pokud je kolizí málo a tabulka má dostatečnou kapacitu
- Nutnost udržovat nízký faktor zatížení (počet prvků vůči kapacitě tabulky) pro udržení dobrého výkonu
Při použití otevřeného adresování hashování je důležité zajistit, že hash tabulka má dostatečnou kapacitu a je pravidelně zvětšována nebo zmenšována podle počtu prvků. To pomáhá minimalizovat počet kolizí a udržet dobrou efektivitu vyhledávání, přidávání a odebírání prvků.
Schémata řešení kolizí
Schémata řešení kolizí jsou metody, které se používají k řešení kolizí v hash tabulkách. Kolize nastávají, když dva různé prvky mají stejnou hash hodnotu nebo jsou mapovány na stejnou pozici v tabulce. Zde jsou některá základní schémata řešení kolizí:
- Řetězení (Chaining):
- Každá pozice v hash tabulce obsahuje ukazatel na externí datovou strukturu (např. spojový seznam nebo strom)
- Při kolizi se nový prvek přidá do datové struktury spojené s danou pozicí
- Výhody: Jednoduché řešení, které umožňuje vysoký faktor zatížení
- Nevýhody: Vyžaduje více paměti pro externí datové struktury a může způsobit zpomalení při mnoha kolizích
- Otevřené adresování (Open Addressing):
- Všechny prvky jsou uloženy přímo v hash tabulce
- Při kolizi se hledá volné místo v tabulce pomocí různých metod (např. lineární sondování, kvadratické sondování, dvojité hashování)
- Výhody: Nižší režie paměti a může být rychlejší než řetězení, pokud je kolizí málo
- Nevýhody: Nutnost udržovat nízký faktor zatížení a složitější řešení
- Koalescentní hashování (Coalesced Hashing):
- Kombinuje vlastnosti řetězení a otevřeného adresování
- Při kolizi se nový prvek přidá na volné místo v tabulce a spojí se s předchozím prvkem v kolizním řetězci
- Výhody: Lepší využití paměti než řetězení a může být rychlejší než otevřené adresování
- Nevýhody: Složitější implementace a může být pomalejší než otevřené adresování při nízkém faktoru zatížení
- Perfect hashing (Perfektní hashování):
- Používá dvě úrovně hashovacích funkcí pro zajištění, že nebudou žádné kolize
- První úroveň rozděluje prvky do skupin, druhá úroveň použije samostatnou hashovací funkci pro každou
Bloom filters, complexity, false positives, Bloom filter extensions
Bloom filtry:
Bloom filtry jsou pravděpodobnostní datové struktury, které umožňují testování přítomnosti prvku v množině. Bloom filtry používají více hashovacích funkcí a bitové pole pro uložení informací o prvcích.
Složitost:
- Vkládání: O(k), kde k je počet hashovacích funkcí
- Hledání: O(k), kde k je počet hashovacích funkcí
Falešné pozitivy:
- Bloom filtry mohou vrátit falešné pozitivy (tvrdit, že prvek je v množině, i když tam není), ale nikdy nevracejí falešné negativy (tvrdit, že prvek není v množině, když tam je)
- Pravděpodobnost falešných pozitiv závisí na velikosti bitového pole, počtu hashovacích funkcí a počtu prvků v množině
- Pro zajištění nízké pravděpodobnosti falešných pozitiv je nutné správně naladit parametry Bloom filtru (velikost bitového pole a počet hashovacích funkcí)
Rozšíření Bloom filtrů:
- Scalable Bloom Filters (Škálovatelné Bloom filtry):
- Umožňují dynamicky přizpůsobovat velikost bitového pole a počet hashovacích funkcí podle počtu prvků v množině
- Zajišťují konstantní pravděpodobnost falešných pozitiv při růstu množiny
- Counting Bloom Filters (Počítací Bloom filtry):
- Rozšiřují klasické Bloom filtry tím, že udržují počet výskytů prvku místo jednoduché přítomnosti
- Umožňují přidávání i odebírání prvků, avšak za cenu vyšší režie paměti
- Cuckoo Filters (Kukaččí filtry):
- Vylepšení Bloom filtrů, které umožňují efektivnější práci s pamětí a poskytují lepší výkon pro testování přítomnosti prvku v množině
- Používají kukaččí hashování pro řešení kolizí a udržují pouze část informací o prvku (např. fingerprint)
- Invertible Bloom Lookup Tables (Invertibilní Bloom vyhledávací
tabulky):
- Rozšiřují Bloom filtry tím, že umožňují ukládat a získávat páry klíč-hodnota
- Umožňují pokročilé operace, jako je sjednocení, průnik a rozdíl mezi množinami klíčů a hodnot
- Využívají lineární sondování a kompresi dat pro efektivní využití paměti a rychlé vyhledávání
- Space-saving Bloom Filters (Úsporné Bloom filtry):
- Optimalizují paměťovou náročnost Bloom filtrů tím, že dynamicky přizpůsobují velikost bitového pole a počet hashovacích funkcí
- Využívají metody pro odhad pravděpodobnosti falešných pozitiv a minimalizují paměťovou režii při udržení požadované úrovně přesnosti
- DLeft Counting Bloom Filters (DLeft Počítací Bloom filtry):
- Kombinují vlastnosti DLeft hashování a počítacích Bloom filtrů pro efektivní ukládání a vyhledávání páry klíč-hodnota
- Umožňují přidávání, odebírání a aktualizaci prvků s nízkou pravděpodobností falešných pozitiv a efektivním využitím paměti
- Layered Bloom Filters (Vrstvené Bloom filtry):
- Využívají více vrstev Bloom filtrů s různými parametry pro rychlé vyhledávání a eliminaci falešných pozitiv
- Umožňují postupně zvyšovat přesnost vyhledávání při zachování rychlosti a efektivnosti paměti
Tyto rozšíření Bloom filtrů řeší různé úkoly a výzvy spojené s testováním přítomnosti prvku v množině, přičemž každé rozšíření se zaměřuje na konkrétní aspekt, jako je škálovatelnost, dynamické přidávání a odebírání prvků, efektivita paměti nebo podpora pro práci s páry klíč-hodnota.
Reference types - weak, soft, phantom
- Silné reference (Strong references):
- Běžné reference, které používáme při práci s objekty
- Pokud je objekt dosažitelný přes silnou referenci, nebude uvolněn garbage collectorem
- Slabé reference (Weak references):
- Vytváříme je pomocí třídy
java.lang.ref.WeakReference - Pokud je objekt dosažitelný pouze přes slabé reference, může být kdykoliv uvolněn garbage collectorem
- Často používány pro implementaci cache, která se automaticky uvolní při nedostatku paměti
- Vytváříme je pomocí třídy
- Měkké reference (Soft references):
- Vytváříme je pomocí třídy
java.lang.ref.SoftReference - Pokud je objekt dosažitelný pouze přes měkké reference, může být uvolněn garbage collectorem, ale pouze pokud je potřeba uvolnit paměť
- Užitečné pro implementaci cache, která se udržuje v paměti, dokud není potřeba uvolnit prostředky
- Vytváříme je pomocí třídy
- Fantomové reference (Phantom references):
- Vytváříme je pomocí třídy
java.lang.ref.PhantomReference - Neslouží k přístupu k objektu, ale pouze k zaznamenání, že byl objekt uvolněn garbage collectorem
- Užitečné pro sledování životního cyklu objektů a provádění úklidu po uvolnění objektu
- Vytváříme je pomocí třídy
Tyto různé typy referencí nám umožňují pracovat s objekty v Javě různými způsoby a ovlivňovat chování garbage collectoru při uvolňování paměti. Slabé, měkké a fantomové reference nám umožňují vytvářet pokročilé datové struktury a algoritmy, které pracují efektivně s omezenými zdroji a reagují na potřeby aplikace.
Alokace objektů v JVM:
- Mladá generace (Young Generation):
- Většina objektů je alokována v mladé generaci
- Mladá generace se dělí na tři části:
- Eden: místo, kde jsou všechny nové objekty alokovány
- Survivor 1 (S0) a Survivor 2 (S1): slouží k ukládání objektů, které přežily garbage collection v Eden prostoru
- Alokace objektu:
- Objekt je nejprve alokován v Eden prostoru
- Pokud Eden prostor dosáhne kapacity, spustí se garbage collection (tzv. minor GC) pro mladou generaci
- Objekty, které přežijí minor GC, jsou přesunuty do jednoho z Survivor prostorů (S0 nebo S1)
- Promoci objektu do staré generace:
- Pokud objekt přežije určitý počet minor GC (záleží na nastavení JVM), je promován do staré generace
- Stará generace obsahuje objekty, které přežily více garbage collection a jsou pravděpodobněji dlouhodobě používány
- Alokace velkých objektů:
- Velké objekty, které nemohou být alokovány v mladé generace, jsou přímo alokovány v staré generaci
- Garbage collection pro starou generaci:
- Pokud stará generace dosáhne kapacity, spustí se garbage collection (tzv. major GC nebo full GC) pro celou heap
- Major GC je náročnější na výkon a trvá déle než minor GC
Alokace objektů v JVM je optimalizována pro efektivní správu paměti a rychlé uvolňování krátkodobě žijících objektů. Garbage collector a generace paměti pomáhají minimalizovat dopad na výkon při uvolňování paměti.
Thread-Local Allocation Buffers (TLAB)
- Co je TLAB?
- TLAB je část paměti Eden prostoru v mladé generaci, která je vyhrazena pro alokaci objektů jednoho konkrétního vlákna
- Každé vlákno má svůj vlastní TLAB, což umožňuje alokovat objekty rychleji bez nutnosti synchronizace mezi vlákny
- Výhody TLAB:
- Snížení režie spojené s synchronizací vláken při alokaci objektů
- Rychlejší alokace objektů, protože každé vlákno může alokovat objekty ve svém TLAB bez čekání na ostatní vlákna
- Zlepšení výkonu aplikací s vysokou mírou paralelismu a vytvářením objektů
- Jak TLAB funguje?
- Při inicializaci JVM se pro každé vlákno vytvoří TLAB v Eden prostoru
- Každé vlákno alokuje objekty pouze ve svém TLAB
- Pokud je TLAB jednoho vlákna plný, může být přidělena nová část paměti z Eden prostoru, nebo se může spustit garbage collection
- Nastavení a ladění TLAB:
- Velikost TLAB může být nastavena pomocí JVM parametrů, např.
-XX:TLABSize=<velikost> - Pro ladění TLAB lze použít JVM parametry, např.
-XX:+PrintTLABpro výpis informací o TLAB do logu
- Velikost TLAB může být nastavena pomocí JVM parametrů, např.
TLAB zvyšuje výkon JVM tím, že minimalizuje režii spojenou s alokací objektů v paralelním prostředí. Tím se zlepšuje celková efektivita paměti a výkon aplikací s vysokou mírou vytváření objektů.
Analýza úniku objektů (Object Escape Analysis):
- Co je analýza úniku objektů?
- Optimalizační technika používaná JVM pro identifikaci objektů, které neuniknou z aktuálního kontextu metody nebo vlákna
- Pokud objekt neunikne, může JVM optimalizovat jeho alokaci a synchronizaci, což zlepšuje výkon aplikace
- Výhody analýzy úniku objektů:
- Snížení režie spojené s alokací objektů na haldě
- Odstranění zbytečných synchronizací, které nejsou potřeba pro objekty, které neuniknou z aktuálního kontextu
- Možnost alokovat objekty na zásobníku místo na haldě, což zlepšuje výkon a zjednodušuje práci garbage collectoru
- Jak analýza úniku objektů funguje?
- JVM analyzuje kód aplikace za běhu nebo při kompilaci a identifikuje objekty, které neuniknou z aktuálního kontextu metody nebo vlákna
- Pokud objekt neunikne, JVM může provést následující optimalizace:
- Alokace objektu na zásobníku místo na haldě
- Odstranění zbytečných synchronizací na objektu
- Optimalizace práce garbage collectoru
- Nastavení a ladění analýzy úniku objektů:
- Analýza úniku objektů je ve většině JVM aktivována automaticky
- Pro ladění analýzy úniku objektů lze použít JVM parametry, např.
-XX:+DoEscapeAnalysispro zapnutí analýzy úniku objektů
Analýza úniku objektů je důležitá optimalizační technika, která zlepšuje výkon a efektivitu paměti aplikací. Pomáhá JVM identifikovat objekty, které neuniknou z aktuálního kontextu, a provádět optimalizace, které snižují režii spojenou s alokací objektů a synchronizací.
Lokalita dat (Data Locality):
- Co je lokalita dat?
- Lokalita dat se týká organizace dat v paměti tak, aby byla přístupná rychle a efektivně
- Zaměřuje se na způsob, jakým jsou data uložena a uspořádána v paměti, aby byla minimalizována doba přístupu a režie
- Existují dva druhy lokality dat: lokalita v čase a lokalita v prostoru
- Lokalita v čase (Temporal Locality):
- Pokud je prvek použit, je pravděpodobné, že bude opět použit v blízké budoucnosti
- Optimalizace: ukládání často používaných dat v rychlých cache pamětech
- Lokalita v prostoru (Spatial Locality):
- Pokud je prvek použit, je pravděpodobné, že budou použity i jeho sousední prvky v blízké budoucnosti
- Optimalizace: načítání bloků dat do cache paměti, které obsahují i sousední prvky
- Výhody lokality dat:
- Zlepšení výkonu aplikace díky rychlejšímu přístupu k datům
- Efektivnější využití cache paměti a minimalizace cache miss
- Menší režie spojená s načítáním a ukládáním dat
- Aplikace lokality dat v programování:
- Použití kontiguálních datových struktur (např. pole) místo spojových datových struktur (např. spojový seznam)
- Uspořádání dat v paměti podle přístupových vzorů (např. skupinování souvisejících dat dohromady)
- Optimalizace smyček a algoritmů pro využití lokality dat (např. procházení pole po řádcích nebo sloupcích)
Lokalita dat je klíčovým aspektem optimalizace výkonu aplikací. Správné uspořádání a organizace dat v paměti může významně zlepšit výkon aplikace a minimalizovat režii spojenou s načítáním a ukládáním dat.
Nerovnoměrná alokace paměti (Non-Uniform Memory Allocation, NUMA):
- Co je nerovnoměrná alokace paměti (NUMA)?
- NUMA je architektura paměti, která se používá v multiprocesorových systémech, kde je přístup k paměti různě rychlý v závislosti na vzdálenosti mezi procesorem a pamětí
- Cílem NUMA je zlepšit výkon a škálovatelnost systému tím, že se sníží režie spojená s přístupem k paměti
- Jak NUMA funguje?
- V NUMA architektuře je paměť rozdělena do několika menších paměťových uzlů, které jsou připojeny k procesorům
- Každý procesor má rychlejší přístup k paměti ve svém vlastním uzlu a pomalejší přístup k paměti v ostatních uzlech
- Při alokaci paměti se pokouší NUMA alokovat paměť v uzlu, který je nejblíže procesoru, který bude paměť používat
- Výhody NUMA:
- Zlepšení výkonu a škálovatelnosti multiprocesorových systémů díky rychlejšímu přístupu k lokální paměti
- Menší režie spojená s přístupem k paměti, protože paměťová komunikace probíhá většinou uvnitř uzlů
- Možnost efektivnějšího využití cache paměti
- Nevýhody NUMA:
- Složitější správa paměti a plánování procesů
- Potenciální problémy s latencí a propustností při přístupu k vzdálené paměti
- Vyšší nároky na hardware a softwarovou podporu
- Jak optimalizovat aplikace pro NUMA?
- Správné rozdělení práce mezi procesory a jejich lokálními paměťovými uzly
- Využití NUMA-optimálních knihoven a funkcí pro správu paměti
- Monitorování a ladění výkonu aplikace v NUMA systémech
Nerovnoměrná alokace paměti (NUMA) je architektura paměti používaná v multiprocesorových systémech pro zlepšení výkonu a škálovatelnosti. Správné využití NUMA může významně zlepšit výkon aplikace v multiprocesorových prostředích.
OSI model (Open Systems Interconnection):
- Co je OSI model?
- OSI model je konceptuální rámec, který popisuje, jak různé vrstvy komunikačního systému spolupracují při přenosu dat mezi síťovými zařízeními
- Model se skládá ze 7 vrstev, které definují různé úrovně abstrakce a funkcí komunikačního procesu
- Seznam vrstev OSI modelu:
- Fyzická vrstva (Physical Layer)
- Linková vrstva (Data Link Layer)
- Síťová vrstva (Network Layer)
- Transportní vrstva (Transport Layer)
- Relační vrstva (Session Layer)
- Prezentační vrstva (Presentation Layer)
- Aplikační vrstva (Application Layer)
- Popis vrstev OSI modelu:
- Fyzická vrstva:
- Zajišťuje přenos a přijímání bitů přes fyzické médium (např. kabel, rádiové vlny)
- Definuje fyzické charakteristiky konektorů, kabelů a signálů
- Linková vrstva:
- Řeší přenos datových rámců mezi sousedními uzly v síti
- Zajišťuje kontrolu chyb a řízení toku dat
- Síťová vrstva:
- Zajišťuje směrování a přeposílání datových paketů mezi různými sítěmi
- Spravuje adresování a segmentaci dat
- Transportní vrstva:
- Zajišťuje spolehlivý přenos dat mezi koncovými uzly
- Řídí tok dat, kontrolu chyb a obnovu ztracených dat
- Relační vrstva:
- Řídí spojení mezi aplikacemi a zajišťuje jejich správnou funkci
- Udržuje a ukončuje komunikační relace
- Prezentační vrstva:
- Zajišťuje převod dat mezi aplikacemi a síťovým formátem
- Řídí kódování, kompresi a šifrování dat
- Aplikační vrstva:
- Poskytuje rozhraní mezi aplikacemi a komunikačními službami
- Zajišťuje přístup k síťovým službám, jako jsou e-mail, webové stránky a databáze
- Fyzická vrstva:
OSI model je důležitým konceptem v oblasti počítačových sítí, který pomáhá porozumět základním principům komunikace mezi síťovými zař
Problém C10K
- Co je problém C10K?
- Problém C10K je výkonový problém spojený se schopností serveru zvládat více než 10 000 současných síťových spojení
- Tento problém byl poprvé popsán v roce 1999 a odráží výzvy spojené s růstem počtu uživatelů a potřeby serverů zvládat více spojení
- Příčiny problému C10K:
- Omezení výkonu způsobená tradičními síťovými modely (jako je model jeden proces/jeden vlákno na jedno spojení)
- Vysoká režie spojená s vytvářením a zrušením vláken nebo procesů pro každé spojení
- Nedostatek operačního systému a hardwarové podpory pro vysoký počet současných spojení
- Řešení problému C10K:
- Použití vícevláknových nebo asynchronních modelů serverů, které mohou zpracovávat více spojení pomocí méně zdrojů
- Využití funkce epoll (Linux) nebo kqueue (BSD, macOS) pro efektivní sledování stavu více síťových spojení
- Použití non-blocking I/O operací, které umožňují serveru pokračovat v práci, zatímco čeká na dokončení I/O operace
- Optimalizace operačního systému a hardwaru pro zvýšení propustnosti a snížení režie spojené s přenosem dat
- Význam řešení problému C10K:
- Zlepšení výkonu serverů a schopnosti zvládat vyšší zátěž
- Zajištění škálovatelnosti serverů, které mohou růst spolu s počtem uživatelů a potřebami aplikací
- Umožnění efektivnějšího využití zdrojů serverů, což vede ke snížení nákladů na provoz a správu
Problém C10K odráží výzvy spojené se zvládáním velkého počtu současných síťových spojení na serverech. Řešení tohoto problému zahrnuje použití vícevláknových, asynchronních nebo non-blocking modelů serverů, optimalizaci operačního systému a hardwaru a využití pokročilých technologií pro sledování a správu síťových spojení.
Blocking a non-blocking I/O (vstup/výstup):
- Co je blocking I/O?
- Blocking I/O je metoda vstupu/výstupu, při které se vykonávání programu zastaví, dokud nebude dokončena I/O operace
- Během čekání na dokončení I/O operace je proces nebo vlákno blokováno a nemůže vykonávat žádné další úkoly
- Co je non-blocking I/O?
- Non-blocking I/O je metoda vstupu/výstupu, při které se vykonávání programu nepozastavuje, dokud nebude dokončena I/O operace
- Místo čekání na dokončení I/O operace může proces nebo vlákno pokračovat v jiných úkolech a zpět ke zpracování I/O operace se vrátí, až bude hotova
- Porovnání blocking a non-blocking I/O:
- Výkon: Non-blocking I/O může zlepšit výkon aplikací tím, že minimalizuje čas strávený čekáním na dokončení I/O operací
- Složitost: Blocking I/O je jednodušší na implementaci a pochopení, zatímco non-blocking I/O vyžaduje více pozornosti k správě asynchronních operací
- Vhodnost: Blocking I/O je vhodný pro aplikace, kde je čekání na I/O operace přijatelné nebo očekávané, zatímco non-blocking I/O je vhodný pro aplikace, které vyžadují vysokou propustnost a odezvu
- Příklady použití blocking a non-blocking I/O:
- Blocking I/O: Jednoduché servery, které obsluhují malý počet klientů nebo aplikace, které nevyžadují vysokou propustnost
- Non-blocking I/O: Webové servery, databázové servery nebo aplikace, které obsluhují velké množství současných spojení nebo vyžadují rychlou odezvu
Blocking a non-blocking I/O představují dva různé přístupy k vstupu/výstupu v aplikacích. Blocking I/O je jednodušší na implementaci, ale může vést k nižšímu výkonu. Non-blocking I/O poskytuje lepší výkon, ale vyžaduje více pozornosti k správě asynchronních operací.
Vícevláknový server (Threading server):
- Co je vícevláknový server?
- Vícevláknový server je typ serveru, který používá více vláken pro obsluhu více klientů nebo požadavků současně
- Každé vlákno zpracovává jeden nebo více klientů nezávisle na ostatních vláknech
- Výhody vícevláknového serveru:
- Lepší využití zdrojů: Vícevláknový server může efektivněji využívat zdroje procesoru a paměti, což zlepšuje výkon a propustnost
- Rychlejší odezva: Vícevláknový server může poskytovat rychlejší odezvu na požadavky klientů, protože jednotlivá vlákna mohou pracovat paralelně a zpracovávat více požadavků současně
- Škálovatelnost: Vícevláknový server může lépe zvládat zvýšenou zátěž, protože může vytvářet a zrušit vlákna podle potřeby
- Nevýhody vícevláknového serveru:
- Složitost: Vícevláknový server může být složitější na implementaci a správu, protože vyžaduje koordinaci a synchronizaci mezi vlákny
- Režie: Vytváření a zrušení vláken může způsobit režii, která může snížit výkon serveru
- Sdílené prostředky: Vlákna musí sdílet prostředky, jako je paměť a procesor, což může vést k problémům s výkonem a synchronizací
- Použití vícevláknového serveru:
- Vícevláknový server je vhodný pro aplikace, které vyžadují vysokou propustnost a rychlou odezvu, jako jsou webové servery, databázové servery nebo aplikace pro zpracování videa
Vícevláknový server představuje přístup k zpracování požadavků klientů, který umožňuje lepší využití zdrojů a rychlejší odezvu. Je vhodný pro aplikace, které vyžadují vysokou propustnost a rychlou odezvu, ale může být složitější na implementaci a správu než jednovláknové servery.
Událostmi řízený server (Event-driven server):
- Co je událostmi řízený server?
- Událostmi řízený server je typ serveru, který zpracovává požadavky klientů na základě událostí, jako jsou příchozí data nebo změny stavu spojení
- Server reaguje na události pomocí asynchronních I/O operací a zpracovává požadavky klientů bez potřeby vytvářet samostatná vlákna nebo procesy pro každé spojení
- Výhody událostmi řízeného serveru:
- Nižší režie: Událostmi řízený server má nižší režii než vícevláknový server, protože nepotřebuje vytvářet a zrušit vlákna pro každé spojení
- Škálovatelnost: Událostmi řízený server může zvládat velký počet současných spojení s menšími nároky na systémové zdroje
- Jednodušší koordinace: Událostmi řízený server může být jednodušší na koordinaci a správu než vícevláknový server, protože většina operací je asynchronní a nemusí být koordinována s ostatními vlákny
- Nevýhody událostmi řízeného serveru:
- Složitost: Událostmi řízený server může být složitější na implementaci, protože vyžaduje správu asynchronních událostí a I/O operací
- Výkon: Událostmi řízený server může mít nižší výkon než vícevláknový server, pokud je zátěž serveru nevyvážená nebo pokud server musí provádět náročné výpočetní úkoly
- Použití událostmi řízeného serveru:
- Událostmi řízený server je vhodný pro aplikace, které potřebují zvládat velké množství současných spojení s nízkou režií, jako jsou webové servery, proxy servery nebo aplikace pro zpracování zpráv
Událostmi řízený server představuje přístup k zpracování požadavků klientů, který se zaměřuje na asynchronní I/O operace a reaguje na události, jako jsou příchozí data nebo změny stavu spojení. Je vhodný pro aplikace, které potřebují zvládat velké množství současných spo
Event-based input/output approaches
Přístupy k událostmi řízenému vstupu/výstupu (Event-based input/output):
Co je událostmi řízený vstup/výstup (event-based I/O)?
- Událostmi řízený vstup/výstup je asynchronní způsob zpracování I/O operací, který reaguje na události, jako jsou příchozí data nebo změny stavu spojení
- Tento přístup umožňuje efektivně zpracovávat velké množství současných spojení s nízkou režií a vysokou propustností
Přístupy k událostmi řízenému vstupu/výstupu:
- Reactor pattern (Reaktor vzor):
- Reaktor vzor je návrhový vzor, který řídí událostmi řízený vstup/výstup pomocí jednoho nebo více demultiplexorů událostí
- Demultiplexor událostí sleduje události na více I/O zdrojích a spouští příslušné obslužné rutiny, které zpracovávají události
- Reaktor vzor je vhodný pro aplikace s malým počtem současných spojení, které vyžadují rychlou odezvu na události
- Proactor pattern (Proaktor vzor):
- Proaktor vzor je návrhový vzor, který řídí událostmi řízený vstup/výstup pomocí asynchronních I/O operací a plánovače událostí
- Plánovač událostí zodpovídá za řízení a spouštění asynchronních I/O operací a obslužných rutin, které zpracovávají události
- Proaktor vzor je vhodný pro aplikace s velkým počtem současných spojení, které vyžadují vysokou propustnost a efektivní využití systémových zdrojů
- Reactor pattern (Reaktor vzor):
Porovnání událostmi řízených přístupů k vstupu/výstupu:
- Reactor pattern:
- Výhody: Jednodušší na implementaci, rychlá odezva na události
- Nevýhody: Nižší propustnost při velkém počtu současných spojení, vyšší režie při demultiplexingu událostí
- Proactor pattern:
- Výhody: Vysoká propustnost, efektivní využití systémových zdrojů, snížená režie při zpracování událostí
- Nevýhody: Složitější na implementaci, může vyžadovat specifickou podporu asynchronních I/O operací ze strany operačního systému
- Reactor pattern:
Použití událostmi řízených přístupů k vstupu/výstupu:
- Událostmi řízené přístupy k vstupu/výstupu se používají v širokém spektru aplikací, které vyžadují efektivní zpracování velkého počtu současných spojení, jako jsou webové servery, proxy servery, aplikace pro zpracování zpráv nebo databázové servery
Událostmi řízené přístupy k vstupu/výstupu, jako jsou Reactor a Proactor vzory, umožňují efektivně zpracovávat velké množství současných spojení s nízkou režií a vysokou propustností. Tyto přístupy se používají v širokém spektru aplikací, které vyžadují efektivní zpracování velkého počtu současných spojení, jako jsou webové servery, proxy servery, aplikace pro zpracování zpráv nebo databázové servery.
Nativní buffery v JVM (Java Virtual Machine):
- Co jsou nativní buffery?
- Nativní buffery jsou oblasti paměti mimo Java heap, které slouží k ukládání a manipulaci s daty v rámci JVM
- Tyto buffery mohou být přímo přístupné pro nativní kód a operační systém, což umožňuje rychlejší a efektivnější zpracování dat než při použití běžných Java objektů
- Výhody nativních bufferů v JVM:
- Rychlost: Nativní buffery umožňují rychlejší zpracování dat, protože nejsou omezeny Java garbage collector a nemusí být kopírovány mezi Java heap a nativní pamětí
- Efektivita: Nativní buffery umožňují efektivnější využití systémových zdrojů, jako je paměť a I/O, protože mohou být přímo přístupné pro nativní kód a operační systém
- Kompatibilita: Nativní buffery usnadňují interakci mezi Java kódem a nativními knihovnami nebo operačním systémem, což umožňuje vytvářet výkonnější a škálovatelnější aplikace
- Použití nativních bufferů v JVM:
- Nativní buffery se často používají v JVM pro zlepšení výkonu a efektivity aplikací, které pracují s velkým množstvím dat nebo potřebují přímý přístup k nativním knihovnám a operačnímu systému
- Typické příklady zahrnují síťové I/O operace, grafické a multimediální aplikace, databázové servery nebo výkonnostně náročné výpočty
Nativní buffery v JVM umožňují rychlejší a efektivnější zpracování dat než při použití běžných Java objektů, protože nejsou omezeny Java garbage collector a mohou být přímo přístupné pro nativní kód a operační systém. Tyto buffery se často používají pro zlepšení výkonu a efektivity aplikací, které pracují s velkým množstvím dat nebo potřebují přímý přístup k nativním knihovnám a operačnímu systému.
Kanály a selektory:
- Co jsou kanály a selektory?
- Kanály (Channels) jsou abstrakce, které umožňují efektivní a asynchronní komunikaci mezi Java kódem a I/O zdroji, jako jsou soubory, síťové sockety nebo datové proudy
- Selektory (Selectors) jsou komponenty, které sledují a řídí události na více kanálech současně, což umožňuje efektivní zpracování událostí a multiplexing I/O operací
- Výhody kanálů a selektorů:
- Efektivita: Kanály a selektory umožňují efektivní využití systémových zdrojů, jako je paměť a I/O, protože umožňují asynchronní a událostmi řízený přístup k I/O zdrojům
- Flexibilita: Kanály a selektory poskytují jednotné rozhraní pro různé typy I/O zdrojů, což usnadňuje vývoj a údržbu aplikací, které pracují s různými typy dat a komunikací
- Škálovatelnost: Kanály a selektory umožňují efektivní zpracování velkého počtu současných spojení, což je užitečné pro aplikace, které vyžadují vysokou propustnost a nízkou latenci
- Použití kanálů a selektorů v JVM:
- Kanály a selektory se používají v širokém spektru aplikací, které vyžadují efektivní zpracování I/O operací a komunikace, jako jsou webové servery, proxy servery, aplikace pro zpracování zpráv nebo databázové servery
- Kanály a selektory jsou součástí Java NIO (New Input/Output) knihovny, která poskytuje rozšířené a výkonné I/O funkce pro Java aplikace
Kanály a selektory jsou klíčovými komponentami Java NIO knihovny, které umožňují efektivní a asynchronní komunikaci mezi Java kódem a I/O zdroji. Tyto komponenty se používají v širokém spektru aplikací, které vyžadují efektivní zpracování I/O operací a komunikace, jako jsou webové servery, proxy servery, aplikace pro zpracování zpráv nebo databázové servery.
Synchronizace v multithreadových programech (atomické operace, mutex, semafor, rw-lock, spinlock, RCU). Kdy použít který mechanismus? Výkonnostní úzká místa zmíněných mechanismů:
- Atomické operace:
- Použití: Malé, jednoduché a rychlé operace, které mají garantovat konzistenci mezi vlákny
- Výkonnostní úzká místa: Omezená na jednoduché operace, může způsobit zpoždění v případě častých aktualizací dat
- Mutex:
- Použití: Vzájemné vyloučení přístupu k sdíleným zdrojům, vhodné pro krátké kritické sekce
- Výkonnostní úzká místa: Může způsobit zpoždění, pokud je přístup k sdíleným zdrojům často blokován
- Semafor:
- Použití: Omezení počtu současně prováděných operací, například při omezení počtu současných spojení
- Výkonnostní úzká místa: Může způsobit zpoždění v případě velkého počtu vláken čekajících na uvolnění semaforu
- Rw-lock:
- Použití: Oddělení čtecích a zapisovacích operací pro sdílené zdroje, vhodné pro situace s častými čtecími operacemi a méně častými zapisovacími operacemi
- Výkonnostní úzká místa: Může způsobit zpoždění, pokud zapisovací operace často blokují čtecí operace
- Spinlock:
- Použití: Vzájemné vyloučení přístupu k sdíleným zdrojům, vhodné pro velmi krátké kritické sekce, kde je očekávání na uvolnění zámku krátké
- Výkonnostní úzká místa: Může způsobit zvýšení vytížení procesoru, pokud vlákna čekají na uvolnění zámku po delší dobu
- RCU (Read-Copy-Update):
- Použití: Synchronizace čtecích a zapisovacích operací pro sdílené zdroje bez použití zámků, vhodné pro situace s častými čtecími operacemi a méně častými zapisovacími operacemi
- Výkonnostní úzká místa: Může způsobit zpoždění v případě častých zapisovacích operací nebo velkého množství vláken, kvůli nutnosti provádět čištění paměti a koordinaci mezi vlákny
Při výběru synchronizačního mechanismu je důležité zvážit následující faktory:
- Četnost a typ operací (čtení, zápis) prováděných na sdílených zdrojích
- Počet vláken, které přistupují k sdíleným zdrojům
- Očekávané doby čekání na zámky nebo jiné synchronizační mechanismy
- Důležitost výkonu a škálovatelnosti aplikace
Výběr vhodného synchronizačního mechanismu může mít významný dopad na výkon a škálovatelnost aplikace. Je důležité provádět testy a analýzu výkonu, aby bylo zajištěno, že zvolený mechanismus splňuje požadavky aplikace a nepředstavuje výkonnostní úzká místa.
Synchronizace v “read-mostly workloads” (práce s převážně čtecími operacemi), výhody a nevýhody různých synchronizačních mechanismů:
- Atomické operace:
- Výhody: Rychlé, jednoduché a bez zámku
- Nevýhody: Omezené na jednoduché operace, méně vhodné pro složitější sdílené struktury
- Mutex:
- Výhody: Zajišťuje vzájemné vyloučení přístupu k sdíleným zdrojům
- Nevýhody: Může způsobit zpoždění, pokud je přístup k sdíleným zdrojům často blokován
- Read-write lock (rw-lock):
- Výhody: Umožňuje paralelní čtení, odděluje čtecí a zapisovací operace
- Nevýhody: Může způsobit zpoždění, pokud zapisovací operace často blokují čtecí operace
- RCU (Read-Copy-Update):
- Výhody: Bez zámku, umožňuje efektivní čtení bez blokování
- Nevýhody: Může způsobit zpoždění v případě častých zapisovacích operací, kvůli nutnosti provádět čištění paměti a koordinaci mezi vlákny
- StampedLock:
- Výhody: Podpora pro optimalizované čtení bez zámku, oddělení čtecích a zapisovacích operací
- Nevýhody: Složitější použití, může způsobit zpoždění, pokud zapisovací operace často blokují čtecí operace
Pro read-mostly workloads, kde je většina operací čtecích a zapisovací operace jsou méně časté, jsou vhodné mechanismy, které minimalizují dopad zapisovacích operací na čtecí operace a umožňují efektivní paralelní čtení. Mezi takové mechanismy patří rw-lock, RCU a StampedLock.
Výběr vhodného synchronizačního mechanismu závisí na konkrétních požadavcích aplikace a na potřebě optimalizace výkonu a škálovatelnosti. Je důležité provádět testy a analýzu výkonu, aby bylo zajištěno, že zvolený mechanismus splňuje požadavky aplikace a nepředstavuje výkonnostní úzká místa.
Cache-efektivní datové struktury a algoritmy (např. násobení matic):
Cache-efektivní datové struktury a algoritmy jsou navrženy tak, aby minimalizovaly přístupy k paměti a využily cache CPU co nejlépe. Příklady cache-efektivních datových struktur a algoritmů:
- Cache-oblivious algoritmy:
- Navrženy tak, aby efektivně využily cache bez znalosti velikosti cache nebo cache line
- Příklad: Cache-oblivious násobení matic, které rozdělí matice na menší bloky a provádí násobení bloků s efektivním využitím cache
- Cache-aware algoritmy:
- Navrženy s vědomím velikosti cache a cache line, což umožňuje maximalizovat využití cache
- Příklad: Cache-aware násobení matic, které rozdělí matice na bloky velikosti, která odpovídá velikosti cache, a násobí bloky efektivně
- B-stromy:
- Cache-efektivní stromová datová struktura, která má větší větve než binární stromy, což umožňuje efektivnější využití cache
- Příklad: B-stromy se používají v databázových systémech a souborových systémech pro efektivní vyhledávání a manipulaci s daty
- Bloom filtry:
- Cache-efektivní datová struktura, která umožňuje rychlé a efektivní testování přítomnosti prvku v množině s malou paměťovou náročností
- Příklad: Bloom filtry se používají pro rychlé vyhledávání v cache nebo pro detekci duplicitních dat
- Compact hash tabulky:
- Cache-efektivní varianta hash tabulek, která minimalizuje paměťovou náročnost a zlepšuje využití cache
- Příklad: Compact hash tabulky se používají pro rychlé vyhledávání a ukládání dat s malou paměťovou náročností
Pro dosažení cache-efektivity je důležité brát v úvahu vlastnosti paměti cache, jako je velikost cache, cache line, asociativita a politika nahrazování. Cache-efektivní algoritmy a datové struktury mohou výrazně zlepšit výkon aplikace tím, že minimalizují přístupy k pomalejší hlavní paměti a maximalizují využití rychlé cache paměti.
Zásady cache pamětí a různé druhy cache chyb:
Cache paměť je rychlá a menší paměť mezi CPU a hlavní pamětí (RAM), která zlepšuje výkon tím, že udržuje kopie často používaných dat z hlavní paměti. Cache paměť využívá vlastnosti prostorové a časové lokalitě přístupu k datům.
Různé druhy cache chyb (misses):
- Compulsory miss (nevyhnutelná chyba):
- Způsobena prvním přístupem k datům, která nejsou v cache
- Nelze zcela eliminovat, může být minimalizováno efektivním přednačítáním dat do cache
- Capacity miss (kapacitní chyba):
- Způsobena omezenou kapacitou cache paměti, když je počet potřebných dat větší než velikost cache
- Může být zlepšeno zvětšením cache nebo využitím cache-efektivních algoritmů a datových struktur
- Conflict miss (konfliktní chyba):
- Způsobena kolizemi v cache záznamech, kdy různá data mapují na stejnou pozici v cache
- Může být zlepšeno zvýšením asociativity cache, použitím cache-oblivious nebo cache-aware algoritmů
- Coherence miss (koherenční chyba):
- Způsobena nekonzistencí mezi cache pamětí různých procesorů v multiprocesorovém systému
- Může být zlepšeno použitím koherentních protokolů a správných synchronizačních mechanismů
Pro efektivní využití cache pamětí je důležité minimalizovat počet cache chyb a zohlednit vlastnosti cache, jako je velikost cache, cache line, asociativita a politika nahrazování. Cache-efektivní algoritmy a datové struktury mohou výrazně zlepšit výkon aplikace tím, že minimalizují přístupy k pomalejší hlavní paměti a maximalizují využití rychlé cache paměti.
Self-evicting kód:
Self-evicting kód je kód, který je napsán tak, aby se záměrně vyhýbal využití cache paměti nebo z ní byl rychle vytlačen. Tento typ kódu může být užitečný v některých případech, například:
- Pro zabezpečení:
- Když chcete minimalizovat dobu, po kterou citlivá data zůstávají v cache paměti, a snížit tak riziko útoku, který by zneužil přístup k těmto datům (např. cache side-channel útoky)
- Pro účely vyvažování zátěže:
- Když chcete zajistit, že kritické části kódu nebudou vytlačeny z cache paměti méně důležitými částmi kódu, které by mohly vést k výkonnostním problémům
Pro napsání self-evicting kódu je třeba použít techniky, které záměrně zhoršují vlastnosti prostorové a časové lokalitě přístupu k datům a zabraňují jejich uchování v cache paměti. Některé z těchto technik mohou zahrnovat:
- Použití nestandardních přístupových vzorů k datům
- Záměrné prokládání přístupu k různým datovým oblastem, aby byla zvýšena pravděpodobnost vytlačení dat z cache
- Použití technik, které ztěžují předpovědi větví, což zabraňuje efektivnímu přednačítání dat do cache
Je důležité si uvědomit, že self-evicting kód může mít negativní dopad na výkon aplikace v důsledku zvýšených přístupů k pomalejší hlavní paměti. Použití self-evicting kódu by mělo být pečlivě zváženo a použito pouze tam, kde je to opravdu nezbytné.
False sharing - co to je a jak se s tím vypořádat?
False sharing je situace, kdy více vláken v multiprocesorovém nebo multicore systému nezávisle přistupuje k různým datovým položkám, které jsou umístěny ve stejném bloku cache (cache line). Tento přístup může způsobit nežádoucí invalidaci cache line a zvýšení komunikace mezi procesory nebo jádry, což má za následek výkonnostní problémy.
Jak se vypořádat s false sharingem:
- Zarovnání dat:
- Zarovnejte často používaná data na hranice cache line, aby byla
oddělena a nezpůsobovala false sharing. V některých jazycích (např.
C/C++) lze použít direktivy pro zarovnání dat, jako je
alignas().
- Zarovnejte často používaná data na hranice cache line, aby byla
oddělena a nezpůsobovala false sharing. V některých jazycích (např.
C/C++) lze použít direktivy pro zarovnání dat, jako je
- Padding (vyplnění):
- Přidejte padding mezi datovými položkami, které jsou přístupné různými vlákny, aby byly umístěny ve vlastních cache lines. Padding může zahrnovat nevyužité proměnné nebo pole.
- Oddělení dat:
- Oddělte data, která jsou přístupná různými vlákny, do různých datových struktur nebo objektů, aby byla minimalizována pravděpodobnost false sharingu.
- Thread-local storage (úložiště pro vlákna):
- Pokud je to možné, použijte thread-local storage pro data, která jsou specifická pro jednotlivá vlákna. Tím se sníží potřeba sdílet data mezi vlákny a zároveň se minimalizuje false sharing.
- Použití optimalizací kompilátoru:
- Některé kompilátory mohou poskytovat optimalizace pro snížení false sharingu. Prozkoumejte možnosti optimalizace vašeho kompilátoru a zvažte jejich použití.
- Profiling a analýza:
- Použijte nástroje pro profiling a analýzu k identifikaci false sharingu ve vaší aplikaci. Tím získáte informace o kritických oblastech kódu, které mohou být zdrojem false sharingu a mohou být optimalizovány.
Při práci s false sharingem je důležité najít rovnováhu mezi snižováním false sharingu a zachováním paměťové efektivity, protože některé z těchto technik mohou zvýšit paměťovou náročnost aplikace.
Profiling a optimalizace programů v kompilovaných jazycích (např. C/C++):
- Profiling:
- Profiling je proces sběru dat o výkonu a chování programu za účelem
identifikace oblastí, které lze optimalizovat. Nástroje pro profiling v
C/C++ mohou zahrnovat:
gprof: GNU profiler pro měření času stráveného v jednotlivých funkcíchperf: Nástroj pro profiling na úrovni jádra LinuxuValgrind: Nástroj pro analýzu paměti a profiling výkonu
- Profiling je proces sběru dat o výkonu a chování programu za účelem
identifikace oblastí, které lze optimalizovat. Nástroje pro profiling v
C/C++ mohou zahrnovat:
- Optimalizace kompilátoru:
- Kompilátory jako GCC nebo Clang poskytují různé úrovně optimalizace,
které lze nastavit pomocí přepínačů:
-O0: Žádná optimalizace (výchozí)-O1: Optimalizace pro rychlost a velikost kódu-O2: Optimalizace pro rychlost (bez zvýšení velikosti kódu)-O3: Agresivní optimalizace pro rychlost (může zvýšit velikost kódu)-Os: Optimalizace pro velikost kódu-Ofast: Optimalizace pro nejvyšší rychlost (ignoruje striktní standardy)
- Kompilátory jako GCC nebo Clang poskytují různé úrovně optimalizace,
které lze nastavit pomocí přepínačů:
- Optimalizace kódu:
- Ruční optimalizace kódu může zahrnovat následující techniky:
- Smyčkové optimalizace: unrolling, fusion, či blocking
- Minimalizace režie volání funkcí: inlining, tail call optimalizace
- Optimalizace paměťového přístupu: zarovnání dat, cache-friendly algoritmy
- Využití paralelismu: SIMD instrukce, vícevláknové programování
- Snížení režie synchronizace: atomické operace, lock-free algoritmy
- Ruční optimalizace kódu může zahrnovat následující techniky:
- Analýza a ladění:
- Analyzujte a laděte svůj kód za účelem identifikace a řešení
výkonnostních problémů, např. pomocí následujících nástrojů:
gdb: GNU Debugger pro ladění programůstrace: Nástroj pro sledování systémových volání a signálůltrace: Nástroj pro sledování volání knihovenvtune: Profiler a ladící nástroj od Intelu
- Analyzujte a laděte svůj kód za účelem identifikace a řešení
výkonnostních problémů, např. pomocí následujících nástrojů:
Při provádění optimalizací je důležité najít rovnováhu mezi výkonem, čitelností kódu a přenositelností.
Hardwarové čítače výkonu:
Hardwarové čítače výkonu (Hardware Performance Counters, HPC) jsou speciální registry, které integrované do procesoru, umožňují sledovat různé aspekty výkonu a chování procesoru. Tyto čítače mohou poskytovat informace o:
- Počet provedených instrukcí
- Počet provedených cyklů
- Počet cache hitů a missů
- Počet branch (větvení) instrukcí a predikcí
- Počet zápisů a čtení z paměti
- Počet závislostí mezi instrukcemi
- Počet událostí souvisejících s pipeliningem
Tyto informace lze použít k analýze výkonu programu a identifikaci úzkých míst nebo problémů, které lze optimalizovat. Některé nástroje pro práci s hardwarovými čítači výkonu zahrnují:
perf: Nástroj pro profiling na úrovni jádra Linuxu, který podporuje hardwarové čítače výkonu.PAPI: Performance Application Programming Interface, multiplatformní knihovna pro práci s hardwarovými čítači výkonu.Intel VTune: Profiler a ladící nástroj od Intelu, který podporuje hardwarové čítače výkonu.
Při použití hardwarových čítačů výkonu je důležité mít na paměti, že jejich podpora a dostupnost se může lišit mezi různými procesory a architekturami.
Optimalizace řízená profilem (Profile-Guided Optimization, PGO):
Optimalizace řízená profilem (PGO) je technika optimalizace kompilátoru, která používá data získaná z profilingu běhu programu za účelem informování kompilátoru o tom, jak nejlépe optimalizovat kód. PGO zahrnuje následující kroky:
- Kompilace programu s přepínačem pro generování profilovacích
informací (např.
-fprofile-generatev GCC nebo Clang). - Spuštění programu na reprezentativní sadě vstupů, které zahrnují typické scénáře použití, aby byly vygenerovány profilovací data.
- Opětovná kompilace programu s přepínačem pro využití profilovacích
informací (např.
-fprofile-usev GCC nebo Clang).
PGO může přinést následující výhody:
- Lepší optimalizace na úrovni zdrojového kódu: Kompilátor může zohlednit skutečné chování programu při volbě optimalizačních strategií.
- Optimalizace inliningu funkcí: Kompilátor může lépe rozhodnout, které funkce by měly být inlinovány na základě jejich skutečného použití.
- Optimalizace větvení: Kompilátor může předpovědět pravděpodobnost větvících instrukcí a generovat efektivnější kód.
- Optimalizace rozložení kódu: Kompilátor může rozhodnout, jakým způsobem uspořádat kód v paměti pro snížení cache missů.
Je důležité provést profiling na reprezentativní sadě vstupů, aby PGO mohla efektivně zlepšit výkon programu. PGO může mít významný dopad na výkon, ale jeho výsledky se mohou lišit v závislosti na konkrétním programu a jeho použití.
Základy kompilátorů C/C++ - AST, intermediální reprezentace:
- Abstract Syntax Tree (AST):
- AST je stromová struktura, která reprezentuje zdrojový kód programu ve formě, která je snadno zpracovatelná pro další analýzy a transformace.
- AST je vytvořen během syntaktické analýzy zdrojového kódu a zachycuje informace o struktuře kódu, např. deklarace, přiřazení, cykly a podmínky.
- AST slouží jako vstup pro další fáze kompilace, jako je sémantická analýza, optimalizace a generování kódu.
- Intermediální reprezentace (Intermediate Representation, IR):
- IR je zjednodušená reprezentace programu, která slouží jako mezikrok mezi AST a výsledným strojovým kódem.
- IR je navržen tak, aby byl snadno analyzovatelný a modifikovatelný pro optimalizace a transformace kódu.
- Existují různé formy IR, například:
- Three-Address Code (TAC): Lineární sekvence instrukcí, kde každá instrukce má nejvýše tři operandy.
- Static Single Assignment (SSA): IR, ve kterém je každá proměnná přiřazena pouze jednou.
Kompilátory C/C++ jako GCC nebo Clang provádějí několik transformací a optimalizací na úrovni AST a IR před generováním výsledného strojového kódu. Tyto transformace a optimalizace mohou zahrnovat zjednodušení výrazů, inlining funkcí, eliminaci mrtvého kódu, propagaci konstant a mnoho dalších.
Optimalizační průchody na vysoké a nízké úrovni:
- Optimalizace na vysoké úrovni (High-Level Optimization):
- Tyto optimalizace se provádějí na úrovni zdrojového kódu nebo abstraktního syntaktického stromu (AST).
- Cílem je zlepšit výkon programu pomocí transformací, které využívají znalosti o struktuře a sémantice zdrojového kódu.
- Příklady optimalizací na vysoké úrovni:
- Zjednodušení výrazů
- Eliminace mrtvého kódu
- Zabalení (wrapping) a rozbalení (unwrapping) cyklů
- Rozdělení proměnných
- Odstraňování společných podvýrazů
- Optimalizace na nízké úrovni (Low-Level Optimization):
- Tyto optimalizace se provádějí na úrovni intermediální reprezentace (IR) nebo strojového kódu.
- Cílem je zlepšit výkon programu pomocí transformací, které využívají znalosti o architektuře procesoru a paměti.
- Příklady optimalizací na nízké úrovni:
- Alokační optimalizace registrů
- Inlining funkcí
- Sdílení registrů mezi proměnnými
- Optimalizace pipeliningu
- Optimalizace větvení
Kompilátory C/C++ jako GCC nebo Clang provádějí řadu optimalizačních
průchodů na vysoké i nízké úrovni před generováním výsledného strojového
kódu. Tyto průchody mohou být řízeny pomocí přepínačů kompilátoru, které
umožňují nastavit různé úrovně optimalizace, například -O1,
-O2, -O3 a -Os.
KO
Topics
Combinatorial optimization problems - formulation, complexity analysis, algorithms and example applications. BE4M35KO (Course web pages)
Questions
Integer Linear Programming. Shortest paths problem and traveling salesman problem ILP formulations. Branch and Bound algorithm. Problem formulations using ILP. Special ILP problems solvable in polynomial time.
Shortest paths problem. Dijkstra, Bellman-Ford, and Floyd–Warshall algorithms. Shortest paths in directed acyclic graphs. Problem formulations using shortest paths.
Network flows. Maximum flow and minimum cut problems. Ford-Fulkerson algorithm. Feasible flow with balances. Minimum cost flow and cycle-canceling algorithm. Problem formulations using network flows. Maximum cardinality matching.
Knapsack problem. Approximation algorithm, dynamic programming approach, approximation scheme.
Traveling salesman problem. Double-tree algorithm and Christofides algorithm for the metric problem. Local search k-OPT.
Scheduling - problem description and notation. One resource - Bratley algorithm, Horn algorithm. Parallel identical resources - list scheduling, dynamic programming. Project scheduling with temporal constraints - relative order and time-indexed ILP formulations.
Constraint Satisfaction Problem.
AC3 algorithm.
PAG
Topics
Properties of parallel and distributed algorithms. Communication operations for parallel algorithms. Parallel algorithms for linear algebra. BE4M35PAG (Course web pages)
Questions
Describe basic communication operations used in parallel algorithms. Show cost analysis of one-to-all broadcast, all-to-all-broadcast, scatter, and all-to-all personalized communication on a ring, mesh, and hypercube. Describe All-Reduce and Prefix-Sum operations and outline their usage.
Describe performance metrics and scalability for parallel systems. How efficiency of a parallel algorithm depends on the problem size and the number of processors? Derive isoefficiency functions of a parallel algorithm for adding numbers (including communication between processors) and explain how it characterizes the algorithm.
Explain and compare two parallel algorithms for matrix-vector multiplication. Describe a parallel algorithm for matrix-matrix multiplication and explain the idea of Cannon’s algorithm. Discuss the principle and properties of the DNS algorithm used for matrix-matrix multiplication.
Outline the principle of sorting networks and describe parallel bitonic sort, including its scalability. Explain parallel enumeration sort algorithm on PRAM model, including its scalability.
Explain all steps of a parallel algorithm for finding connected components in a graph given by the adjacency matrix. Using an example, illustrate a parallel algorithm for finding a maximal independent set in a sparse graph.
PAL
Topics
Polynomial algorithms for standard graph problems. Combinatorial and number-theoretical algorithms, isomorphism, prime numbers. Search trees and their use. Text search based on finite automata.
Questions
- Notation of asymptotic complexity of algorithms. Basic notation of graph problems - degree, path, circuit, cycle. Graph representations by adjacency, distance, Laplacian and incidence matrices. Adjacency list representation.
- Algorithms for minimum spanning tree (Prim-Jarník, Kruskal, Borůvka), strongly connected components (Kosaraju-Sharir, Tarjan), Euler trail. Union-find problem. Graph isomorphism, tree isomorphism.
- Silně propojená komponenta (SCC) orientovaného grafu je podgraf, kde existuje cesta z každého vrcholu do každého jiného vrcholu v podgrafu.
- Generation and enumeration of combinatorial objects - subsets, k-element subsets, permutations. Gray codes. Prime numbers, sieve of Eratosthenes. Pseudorandom numbers properties. Linear congruential generator.
- Finite automata, regular expressions, operations over regular languages. Bit representation of nondeterministic finite automata. Text search algorithms - exact pattern matching, approximate pattern matching (Hamming and Levenshtein distance), dictionary automata.
Asymptotická složitost algoritmů
- Asymptotická složitost algoritmu popisuje, jak se doba běhu nebo prostorová náročnost algoritmu mění s velikostí vstupních dat. Využívá se pro porovnání efektivnosti algoritmů.
O Notace (Big O)
- Popisuje horní hranici složitosti algoritmu.
- Například:
O(n)znamená, že složitost algoritmu roste lineárně s velikostí vstupu.
Ω Notace (Big Omega)
- Popisuje dolní hranici složitosti algoritmu.
- Například:
Ω(n)znamená, že složitost algoritmu roste alespoň lineárně s velikostí vstupu.
Θ Notace (Big Theta)
- Popisuje přesnou hranici složitosti algoritmu.
- Například:
Θ(n)znamená, že složitost algoritmu roste přesně lineárně s velikostí vstupu.
o Notace (Little O)
- Popisuje horní hranici, kterou algoritmus nikdy nepřekročí.
- Například:
o(n)znamená, že složitost algoritmu roste méně než lineárně s velikostí vstupu.
ω Notace (Little Omega)
- Popisuje dolní hranici, kterou algoritmus vždy překročí.
- Například:
ω(n)znamená, že složitost algoritmu roste více než lineárně s velikostí vstupu.
Základní notace problémů s grafy
Vrchol (Vertex): Základní jednotka grafu, také známý jako uzel.
Hrana (Edge): Spojení mezi dvěma vrcholy v grafu.
Stupeň vrcholu (Degree): Počet hran spojených s daným vrcholem. Pro orientované grafy rozlišujeme stupeň dovnitř (in-degree) a stupeň ven (out-degree).
Cesta (Path): Sekvence vrcholů, kde je každý vrchol spojen s dalším hranou. Cesta je jednoduchá, pokud žádný vrchol nebo hrana není v sekvenci vícekrát.
Cyklus (Cycle): Jednoduchá cesta, která začíná a končí ve stejném vrcholu.
Obvod (Circuit): Cesta, která začíná a končí ve stejném vrcholu. Na rozdíl od cyklu může obsahovat opakující se vrcholy a hrany.
Souslednost (Adjacency): Dva vrcholy jsou sousední, pokud jsou spojeni hranou.
Incidence: Hrana je incidní s vrcholem, pokud vrchol leží na hraně.
Podgraf (Subgraph): Graf tvořený vrcholy a hranami původního grafu.
Kompletní graf (Complete graph): Graf, ve kterém je každý vrchol spojen s každým jiným vrcholem.
Spojitý graf (Connected graph): Graf, ve kterém existuje cesta mezi každým párem vrcholů.
Reprezentace grafů
Matice sousednosti (Adjacency Matrix)
- Kvadratická matice, kde hodnota v i-tém řádku a j-tém sloupci je 1, pokud je mezi vrcholy i a j hrana, a 0, pokud ne.
- Pro neorientovaný graf je matice symetrická.
- Časová složitost pro zjištění sousednosti: O(1).
Matice vzdáleností (Distance Matrix)
- Kvadratická matice, kde hodnota v i-tém řádku a j-tém sloupci je délka nejkratší cesty mezi vrcholy i a j.
- Tato matice je vždy symetrická.
Laplaceova matice (Laplacian Matrix)
- Kvadratická matice definovaná jako D - A, kde D je diagonální matice stupňů vrcholů a A je matice sousednosti.
- Laplaceova matice má několik důležitých vlastností v teorii grafů, včetně vazby na počet stromů krytí grafu.
Matice incidence
- Matice s počtem řádků rovným počtu vrcholů a počtem sloupců rovným počtu hran.
- Hodnota v i-tém řádku a j-tém sloupci je 1, pokud hrana j je incidní s vrcholem i, a 0, pokud ne.
- Pro neorientovaný graf jsou hodnoty pouze 1 a 0. Pro orientovaný graf používáme -1 pro označení směru hrany.
Seznam sousednosti (Adjacency List)
- Pro každý vrchol udržuje seznam všech vrcholů, se kterými je spojen.
- Efektivní pro řešení mnoha problémů v grafech, zejména pro řídké grafy, kde je počet hran mnohem menší než počet vrcholů na druhou.
- Časová složitost pro zjištění sousednosti: O(stupeň vrcholu).
Algoritmy pro minimální kostru grafu
Minimální kostra grafu je podgraf, který spojuje všechny vrcholy, je strom a minimizuje celkovou váhu hran.
Algoritmus Prim-Jarník
- Začněte s libovolným vrcholem a postupně přidávejte nejkratší hranu spojující strom s vrcholem mimo strom.
- Postup:
- Inicializace: Začněte s prázdným stromem a přidejte libovolný vrchol do stromu.
- Hledejte nejkratší hranu spojující vrchol ve stromu s vrcholem mimo strom a přidejte ji do stromu.
- Opakujte krok 2, dokud nebudou všechny vrcholy součástí stromu.
- Složitost času: O(E log V) pro binární haldy, kde E je počet hran a V je počet vrcholů.
Kruskalův algoritmus
- Začněte s prázdným stromem a postupně přidávejte nejkratší hranu, která nevytváří cyklus.
- Postup:
- Inicializace: Začněte s prázdným stromem.
- Seřaďte všechny hrany podle jejich váhy od nejmenší po největší.
- Přidejte do stromu nejkratší hranu, která nevytváří cyklus.
- Opakujte krok 3, dokud nebudou všechny vrcholy spojeny.
- Složitost času: O(E log E) nebo O(E log V) pro hranový seznam nebo matice sousednosti.
Borůvkův algoritmus
- Začněte s lesem, kde každý vrchol je samostatný strom, a postupně přidávejte nejkratší hranu spojující dva stromy.
- Postup:
- Inicializace: Začněte s lesem, kde každý vrchol je samostatný strom.
- Pro každý strom v lese najděte nejkratší hranu spojující strom s vrcholem mimo strom a přidejte ji do stromu.
- Opakujte krok 2, dokud nebude existovat pouze jeden strom (tj. všechny vrcholy jsou spojeny).
- Složitost času: O(E log V) pro binární haldy.
Silně propojené komponenty
Kosaraju-Sharirův algoritmus
- Tento algoritmus provádí dva průchody grafem pomocí DFS (depth-first search).
- Postup:
- Proveďte DFS na originálním grafu a sledujte pořadí dokončení vrcholů.
- Transponujte graf (otočte směr všech hran).
- Proveďte DFS na transponovaném grafu, ale začněte s vrcholem, který byl dokončen jako poslední v prvním průchodu.
- Každý strom DFS vytvořený v druhém průchodu je silně propojená komponenta.
- Časová složitost: O(V + E), kde V je počet vrcholů a E je počet hran.
Tarjanův algoritmus
- Tento algoritmus provede jeden průchod grafem pomocí DFS a identifikuje SCC pomocí nízkých spojů a zásobníku.
- Postup:
- Proveďte DFS na grafu a sledujte pořadí návštěvy vrcholů a nejnižší vrchol dosažitelný z každého vrcholu.
- Během DFS, pokud vrchol je kořenem silně propojené komponenty, pak všechny vrcholy na zásobníku nad a včetně tohoto vrcholu tvoří SCC a jsou odstraněny ze zásobníku.
- Každá silně propojená komponenta je identifikována, když je její kořen navštíven.
- Časová složitost: O(V + E).
Eulerova stezka
- Eulerova stezka je cesta v grafu, která prochází každou hranu přesně jednou.
- Eulerův cyklus je Eulerova stezka, která začíná a končí ve stejném vrcholu.
- Graf má Eulerovu stezku, pokud má nanejvýš dva vrcholy s lichým stupněm. Pokud má graf nula vrcholů s lichým stupněm, má Eulerův cyklus.
- Eulerova stezka se využívá například v problému sedmi královských mostů v Königsbergu, v němž se snažíme najít cestu, která prochází přesně jednou všemi sedmi mosty.
Union-Find
- Union-Find je datová struktura, která řeší problém diskrétních množin.
- Má dvě hlavní operace:
- Find: Zjistí, do jaké množiny patří daný prvek.
- Union: Spojí dvě množiny do jedné.
- Využívá se zejména v algoritmech pracujících s grafy (např. Kruskalův algoritmus).
Naivní implementace
- V nejjednodušší implementaci, každá množina je reprezentována pomocí svého “vedoucího” prvku.
- Operace Find prochází celou strukturu, dokud nenajde vedoucího prvku množiny.
- Operace Union přiřadí vedoucího prvku jedné množiny vedoucímu prvku druhé množiny.
- Časová složitost: O(n) pro obě operace, kde n je počet prvků.
Algoritmus pro nalezení Eulerovy stezky
- Existuje několik algoritmů pro nalezení Eulerovy stezky. Nejjednodušší je Fleuryho algoritmus, ale je neefektivní. Hierholzerův algoritmus je efektivnější.
Fleuryho algoritmus
- Začněte na libovolném vrcholu s lichým stupněm (nebo na libovolném vrcholu, pokud jsou všechny vrcholy sudého stupně).
- Postupně sledujte hrany, přičemž se snažíte vyhnout mostům, pokud je to možné.
- Časová složitost: O(E^2), kde E je počet hran.
Isomorfismus grafů
- Dva grafy jsou izomorfní, pokud existuje bijekce mezi vrcholy grafů tak, že spojení vrcholů je zachováno. To znamená, že grafy jsou “stejné”, pouze jsou jinak popsané nebo nakreslené.
- Problém isomorfismu grafů je rozhodnout, zda jsou dva grafy izomorfní. Tento problém je jedním z mála problémů, jejichž složitost zůstává otevřenou otázkou - nevíme, zda patří do třídy P, NP, nebo je NP-úplný.
Isomorfismus stromů
- Problém isomorfismu stromů je podproblémem isomorfismu grafů, ale je snazší. Existuje lineární algoritmus pro rozhodnutí, zda jsou dva stromy izomorfní.
Algoritmus certifikátů
- Algoritmus certifikátů je metoda pro nalezení isomorfismu grafů.
- Každému grafu přiřadí unikátní “certifikát”, který je stejný pro všechny isomorfní grafy.
- Pokud mají dva grafy stejný certifikát, jsou izomorfní.
Složitost
- Problém isomorfismu grafů je jedním z mála problémů, jejichž třída složitosti je stále nejasná. Je známo, že je v NP, ale není známo, zda je v P nebo je NP-úplný.
- Problém isomorfismu stromů je v P, protože existuje lineární algoritmus pro jeho řešení.
Generování a enumerace kombinatorických objektů
Podmnožiny
- Podmnožina je sada, která obsahuje prvky jiné sady, ale žádné další prvky.
- Každá množina má 2^n podmnožin, kde n je počet prvků v množině.
k-prvkové podmnožiny
- k-prvková podmnožina je podmnožina s k prvky.
- Počet k-prvkových podmnožin je daný kombinačním číslem C(n, k), kde n je počet prvků v množině.
Permutace
- Permutace je uspořádaná sekvence prvků, ve které se každý prvek objevuje jednou.
- Počet permutací n prvků je n!.
Kombinace
- Kombinace je výběr prvků, kde nezáleží na pořadí.
- Počet kombinací k prvků z n je C(n, k) = n! / [k!(n-k)!].
Pořadí
- Pořadí je uspořádaná sekvence prvků, kde se mohou objevit opakování.
- Počet uspořádaní k prvků z n je P(n, k) = n! / (n-k)!.
Grayovy kódy
- Grayovy kódy jsou posloupnost binárních čísel, kde se dvě po sobě jdoucí čísla liší pouze v jednom bitu.
- Při přechodu od jednoho čísla k dalšímu se mění vždy jen jeden bit.
- Často se používají v digitálních systémech, kde je důležité minimalizovat šanci na chybu při změně stavu.
Generování Grayových kódů
- Grayovy kódy lze generovat rekurzivně.
- Pro n-bitový Grayův kód:
- Začněte s listem, který obsahuje jednobitový Grayův kód [0, 1].
- Pro každé další i (až do n):
- Kopírujte list, přidejte ‘0’ na začátek každého čísla v původním listu a přidejte je do nového listu.
- Kopírujte list, přidejte ‘1’ na začátek každého čísla v původním listu, převraťte pořadí a přidejte je do nového listu.
- Toto dá n-bitový Grayův kód.
Prvočísla
- Prvočíslo je přirozené číslo větší než 1, které má pouze dva kladné dělitele: 1 a samo sebe.
- Prvních pět prvočísel: 2, 3, 5, 7, 11.
- 2 je jediné sudé prvočíslo.
Síto Eratosthena
- Algoritmus pro nalezení všech prvočísel menších než dané číslo n.
- Postup:
- Začněte se seznamem všech čísel od 2 do n.
- Označte 2 jako prvočíslo a označte všechny jeho násobky jako složená čísla.
- Přejděte k dalšímu neoznačenému číslu a označte ho jako prvočíslo.
- Označte všechny násobky tohoto nového prvočísla jako složená čísla.
- Opakujte poslední dva kroky, dokud nezůstanou žádná neoznačená čísla.
- Tento algoritmus je účinný a rychlý pro nalezení všech prvočísel menších než n.
Naivní algoritmus pro generování prvočísel
- Pro každé číslo n od 2 výše:
- Zkontrolujte, zda n má nějaké dělitele kromě 1 a n.
- Pokud ne, je to prvočíslo.
- Tento algoritmus je jednoduchý, ale neefektivní pro velké čísla.
Zlepšený naivní algoritmus
- Pro každé číslo n od 2 výše:
- Zkontrolujte, zda n má nějaké dělitele kromě 1 a n, ale jen pro čísla menší než √n.
- Pokud ne, je to prvočíslo.
- Tento algoritmus je stále poměrně pomalý pro velké čísla, ale je rychlejší než úplně naivní algoritmus.
Pseudonáhodná čísla
- Pseudonáhodná čísla jsou čísla, která se zdají být náhodná, ale jsou generována deterministickým algoritmem.
- Kvalitní pseudonáhodný generátor by měl mít následující vlastnosti:
- Uniformita: Každé číslo v požadovaném rozsahu má stejnou šanci na vygenerování.
- Nezávislost: Generovaná čísla nejsou vzájemně závislá.
- Reprodukce: Za stejných počátečních podmínek (seed) generuje stejnou sekvenci čísel.
- Periodicita: Délka sekvence, než se opakuje, by měla být co možná největší.
Lineární kongruentní generátor (LCG)
- Lineární kongruentní generátor je typ pseudonáhodného generátoru čísel.
- Vytváří sekvenci čísel podle vzorce: X_{n+1} = (a * X_n + c) mod m
- Kde:
- X_{n+1} je další číslo v sekvenci,
- X_n je předchozí číslo v sekvenci,
- a, c, a m jsou konstanty.
- Konstanty a, c, a m by měly být pečlivě vybrány, aby byla zajištěna dobrá kvalita generovaných čísel a maximální perioda.
Hull-Dobell Theorem
- Hull-Dobell Theorem stanovuje podmínky, za kterých má LCG plnou periodu pro každé počáteční číslo (seed).
- Podmínky jsou:
- Číslo c a m jsou relativně prvočíselné (tzn. jediné číslo, které dělí jak c tak m, je 1).
- Pokud q je jakýkoli prvočíselný faktor m, pak a-1 je dělitelné q.
- Pokud 4 je dělitel m, pak a-1 je dělitelné 4.
- Pokud jsou splněny všechny tyto podmínky, pak LCG generuje sekvenci s plnou periodou.
Search trees - data structures, operations, and their complexities. Binary tree, AVL tree, red-black tree (RB-tree), B-tree and B+ tree, splay tree, k-d tree. Nearest neighbor searching in k-d trees. Skip list.
Binární strom (Binary tree)
- Binární strom je datová struktura, kde každý uzel má maximálně dva potomky, označované jako levý potomek a pravý potomek.
- Každý uzel obsahuje klíč (nebo data), levý odkaz na potomka, pravý odkaz na potomka.
- Neexistuje žádné zvláštní řazení mezi klíči. Může být úplný, úplný, rostoucí, klesající atd.
- Operace:
- Vložení: O(n)
- Hledání: O(n)
- Mazání: O(n)
- Nejlepší využití: Binární stromy jsou vhodné pro případy, kdy je důležité zachovat přirozené uspořádání dat (např. pro vytváření výrazových stromů v počítačových algoritmech).
AVL strom
- AVL strom je vyvážený binární vyhledávací strom, kde rozdíl výšky levého a pravého podstromu je maximálně 1.
- Po každé operaci vložení nebo mazání se provádí vyvažování stromu.
- Operace:
- Vložení: O(log n)
- Hledání: O(log n)
- Mazání: O(log n)
- Nejlepší využití: AVL stromy jsou nejlepší pro databázové stroje, které často načítají a nikdy neukládají.
Červeno-černý strom (Red-Black tree)
- Červeno-černý strom je druh vyváženého binárního vyhledávacího stromu, kde každý uzel má přidělenou barvu (červenou nebo černou).
- Splňuje následující vlastnosti: kořen je černý, všechny listy jsou černé, pokud je uzel červený, pak oba jeho potomci jsou černí, každá cesta z každého listu k jinému listu obsahuje stejný počet černých uzlů.
- Operace:
- Vložení: O(log n)
- Hledání: O(log n)
- Mazání: O(log n)
- Nejlepší využití: Červeno-černé stromy jsou vhodné pro všeobecné použití v mnoha programovacích jazycích, například v implementacích asociativních polí.
B-strom
- B-strom je samo vyvažující se strom vhodný pro systémy s velkým množstvím dat, které se nedají uchovat v paměti, ale musí být uchovávány na disku.
- Každý uzel v B-stromu může mít více než 2 potomky. Uzel B-stromu s ‘m’ potomky má ‘m-1’ klíčů.
- B-stromy mají pravidlo, že všechny listy musí být na stejné úrovni. To znamená, že B-stromy rostou směrem nahoru.
- B-stromy mají také pravidlo, že všechny uzly (kromě kořene) musí být alespoň z poloviny plné.
- Operace:
- Vložení: O(log n)
- Hledání: O(log n)
- Mazání: O(log n)
- Nejlepší využití: B-stromy jsou široce používány v databázových systémech a souborových systémech.
B+ strom
- B+ strom je vylepšení B-stromu, kde data jsou ukládána pouze v listových uzlech, což umožňuje rychlejší průchod a efektivnější ukládání na disk.
- Interní uzly v B+ stromu ukládají klíče pro navigaci a ukazatele na potomky, ale ne ukládají data. To umožňuje, aby interní uzly měly více klíčů a tedy nižší výšku stromu.
- Všechny listy v B+ stromu jsou navzájem propojeny, což umožňuje rychlé sekvenční přístupy.
- Stejně jako B-strom, B+ strom se vyvažuje při vkládání a mazání.
- Operace:
- Vložení: O(log n)
- Hledání: O(log n)
- Mazání: O(log n)
- Nejlepší využití: B+ stromy jsou široce používány v databázových systémech a souborových systémech, kde je důležitá rychlá sekvenční iterace.
Splay strom
- Splay strom je samo vyvažující se binární vyhledávací strom.
- Klíčová operace je “splay”, kdy se při každé operaci přístupu (vložení, hledání, mazání) přesune přístupovaný uzel na kořen stromu.
- Splay stromy nemají pevnou strukturu jako AVL nebo červeno-černé stromy, a jejich tvar se mění s každou operací.
- Operace:
- Vložení: O(log n) v průměru, ale O(n) v nejhorším případě.
- Hledání: O(log n) v průměru, ale O(n) v nejhorším případě.
- Mazání: O(log n) v průměru, ale O(n) v nejhorším případě.
- Nejlepší využití: Splay stromy jsou dobré pro případy, kdy se některé prvky vyhledávají častěji než ostatní.
k-d strom
- k-d strom (k-dimenzionální strom) je binární vyhledávací strom, kde data v uzlech jsou k-dimenzionální body.
- k-d stromy jsou užitečné pro řadu vyhledávacích úloh, které zahrnují více dimenzí, například rozsahové hledání.
- Operace:
- Vložení: O(log n) v průměru, ale O(n) v nejhorším případě.
- Hledání: O(log n) v průměru, ale O(n) v nejhorším případě.
- Mazání: O(log n) v průměru, ale O(n) v nejhorším případě.
- Nejlepší využití: k-d stromy jsou vhodné pro úlohy, které zahrnují vyhledávání na základě více klíčů (například geografické vyhledávání).
Nearest Neighbor Searching v k-d stromech
Nejbližší soused hledání (Nearest Neighbor Searching, NNS) je algoritmus používaný v k-d stromech k nalezení bodu, který je nejbližší k danému dotazu. Je to důležitá operace pro řadu aplikací v oblasti počítačového vidění, strojového učení a datové analýzy.
Algoritmus
- Začněte na kořeni a procházejte stromem tak, jak byste to udělali při vyhledávání dotazovaného bodu, až narazíte na list.
- Nastavte tento list jako “aktuální nejbližší bod”.
- Vraťte se zpět na rodičovský uzel.
- Zkontrolujte, zda by rodičovský uzel mohl obsahovat bod bližší k dotazovanému bodu než aktuální nejbližší bod. Pokud ano, zkontrolujte, zda je to tak, a případně aktualizujte “aktuální nejbližší bod”.
- Zkontrolujte, zda by jiná větev, než kterou jsme prošli, mohla obsahovat bod bližší k dotazovanému bodu. Pokud ano, projeďte touto větví (začněte od kroku 1) a případně aktualizujte “aktuální nejbližší bod”.
- Pokračujte, dokud nezkontrolujete celý strom.
Složitost
- Pokud je strom vyvážený a data jsou rovnoměrně rozložená, složitost hledání nejbližšího souseda je O(log n).
- V nejhorším případě, kdy strom není vyvážený nebo data jsou seskupená, může být složitost hledání O(n).
Porovnání
| Typ stromu | Složitost vyhledání | Složitost vložení | Složitost mazání | Výhody | Nevýhody |
|---|---|---|---|---|---|
| Binární strom | O(n) | O(n) | O(n) | Přirozené uspořádání dat | Nevyvážené stromy mohou mít vysoké výšky, což vede k neefektivním operacím |
| AVL strom | O(log n) | O(log n) | O(log n) | Dobře vyvážený | Operace vložení a mazání mohou být pomalé kvůli potřebě vyvažování |
| Červeno-černý strom | O(log n) | O(log n) | O(log n) | Dobře vyvážený | Operace vložení a mazání mohou být pomalé kvůli potřebě udržování vlastností stromu |
| B-strom | O(log n) | O(log n) | O(log n) | Dobré pro velké soubory dat | Složitější implementace, může být pomalý pro operace v paměti |
| B+ strom | O(log n) | O(log n) | O(log n) | Rychlé sekvenční přístupy | Interní uzly neukládají data, což může být neefektivní pro některé typy dotazů |
| Splay strom | O(log n) průměrně | O(log n) průměrně | O(log n) průměrně | Často přistupované prvky jsou rychle dostupné | Nevyvážený, může vést k O(n) operacím v nejhorším případě |
| k-d strom | O(log n) průměrně | O(log n) průměrně | O(log n) průměrně | Dobré pro hledání v mnoha dimenzích | Neefektivní pro vysoké dimenze, operace vkládání a mazání mohou být pomalé v některých případech |
Skip-list
- Datová struktura umožňující rychlé vyhledávání, vložení a mazání v seřazeném seznamu.
- Jednoduchý na implementaci.
- Průměrná složitost operací srovnatelná s vyváženými stromy (například AVL, Červeno-černý).
Struktura
- “Víceúrovňový” seřazený spojový seznam.
- Každý prvek má několik ukazatelů na další prvky, umožňující “přeskočit” přes několik prvků.
- Úrovně přeskakování se určují náhodným generátorem
- Hodím kostkou která dá ANO s pravděpodobností p
- Když padne ANO vytvořím pro vložený prvek další level a opakuji hod
- Když NE vložím prvek s počtem “naházených” linků a předělám reference skoků
Fungování
- Vyhledávání: Začněte na vrcholu a postupujte doprava, dokud následující prvek není větší než hledaný. Poté jděte dolů a opakujte, dokud nenajdete prvek.
- Vložení: Vložte prvek do seznamu na správné místo a rozhodněte o počtu ukazatelů pomocí náhodného procesu
- Mazání: Nalezněte prvek a odstraňte ho ze všech seznamů, na kterých se nachází.
Složitost
- Vyhledávání: O(log n) průměrně
- Vložení: O(log n) průměrně
- Mazání: O(log n) průměrně
Výhody
- Jednoduchost implementace.
- Vysoká rychlost operací v praxi.
- Nepotřebuje dodatečné paměťové nároky jako vyvážené stromy.
Nevýhody
- V nejhorším případě mohou operace trvat O(n).
- Nezaručuje vyváženost, jako vyvážené stromy.
Konečné automaty, regulární výrazy a operace nad regulárními jazyky
Konečné automaty (Finite Automata)
- Konečný automat je model výpočtu, který funguje v diskrétních krocích.
- Dvě hlavní kategorie: Deterministické konečné automaty (DFA) a Nedeterministické konečné automaty (NFA).
- DFA má v každém stavu pro každý symbol vstupní abecedy přesně jedno přechodové pravidlo.
- NFA může mít více přechodových pravidel pro daný stav a symbol a může mít epsilon přechody.
Regulární výrazy (Regular Expressions)
- Notace pro popis regulárních jazyků.
- Základní operace: konkatenace, unie (reprezentovaná znakem
|), a Kleeneho hvězda (reprezentovaná znakem*). - Například, regulární výraz
a*breprezentuje jazyk, který obsahuje libovolný počet ‘a’ následovaný jedním ‘b’.
Operace nad regulárními jazyky
- Unie: Množina slov, které jsou v jednom nebo druhém jazyku.
- Konkatenace: Množina slov, která se skládá ze slov z jednoho jazyka následovaných slovy z druhého jazyka.
- Kleeneho hvězda: Množina slov, které se skládají z libovolného počtu slov z daného jazyka.
- Průnik: Množina slov, které jsou současně v obou jazycích.
- Rozdíl: Množina slov, které jsou v jednom jazyku, ale nejsou v druhém.
Všechny tyto operace vytvářejí regulární jazyky z regulárních jazyků, což je důležitá vlastnost regulárních jazyků.
Bitová reprezentace nedeterministických konečných automatů (NFA)
Nemůžu najít
Algoritmy pro vyhledávání textu
Přesné vyhledávání vzorců
- Přesné vyhledávání vzorců se snaží najít všechny výskyty konkrétního vzorce v textu.
- Příklady algoritmů: Knuth-Morris-Pratt, Boyer-Moore, Rabin-Karp.
Aproximativní vyhledávání vzorců
Aproximativní vyhledávání vzorců se snaží najít výskyty vzorce v textu, které mohou obsahovat chyby (vložení, vymazání, substituce).
Dvě běžné metriky pro měření “vzdálenosti” mezi vzorcem a textem jsou Hammingova a Levenshteinova vzdálenost.
Hammingova vzdálenost: Počet pozic, na kterých se dvě řetězce stejné délky liší.
Levenshteinova vzdálenost (editační vzdálenost): Minimální počet jednotkových operací (vložení, vymazání, substituce), potřebných k převedení jednoho řetězce na druhý.
Automaty pro vyhledávání ve slovníku
- Automaty pro vyhledávání ve slovníku jsou efektivní pro vyhledávání mnoha vzorců současně.
- Příkladem je Aho-Corasickův algoritmus, který vytváří trie (prefixový strom) ze všech vzorců a poté prochází textem, aby našel výskyty vzorců.
SWA
Topics
Software architectures, their parameters and qualitative metrics. Architectural patterns, styles and standards. BE4M36SWA (Course web pages)
Questions
- Describe Krutchen’s 4+1 View Model of a software architecture. Explain how it captures the complete behavior of a developed software from multiple perspectives of the system. How is this model aligned with the UML models?
- What is a software architecture? Describe the importance of software architecture when developing a system. What are the software architecture design guidelines? What are the architectural styles? Give an example of an architectural style and describe it in detail.
- What is a design pattern? What problem are design patterns solving? What types of design patterns exist? Why is it important to know the design patterns? Are there design antipatterns?
- What is a microservice architecture? What are its advantages and disadvantages compared to a monolithic architecture. How is microservices development different from developing a monolithic application? Are there any methodologies or guidelines or best practices to follow when developing microservices? Obviously, there are patterns that can be applied in this area, are there any antipatterns that should be avoided?
- Software architects can choose one architecture over another. The choice may affect the quality of the final product. Can you tell if one architecture is better than another or if one architecture is bad while the other is not? How can you measure the quality of an architecture? Can you measure the quality from different perspectives?
Popis Krutchenova 4+1 View Modelu softwarové architektury:
- Pohled logický (Logical View):
- Zobrazuje třídy, objekty, rozhraní a jejich vztahy
- Zaměřuje se na funkcionalitu systému
- Pohled procesní (Process View):
- Popisuje procesy a konkurenci v systému
- Zaměřuje se na výkonnost, škálovatelnost a stabilitu
- Pohled fyzický (Physical View):
- Popisuje mapování softwarových komponent na hardware
- Zaměřuje se na nasazení a distribuci systému
- Pohled vývojový (Development View):
- Zobrazuje organizaci zdrojového kódu, knihoven a komponent
- Zaměřuje se na správu kódu a modulární strukturu
- Scénáře (Scenarios):
- Uplatňuje se pro ověření a validaci návrhu architektury
- Pomáhá provést průřez všemi čtyřmi pohledy
Jak 4+1 View Model zachycuje chování softwaru z různých perspektiv:
- A. Logický pohled (Logical View):
- Poskytuje abstraktní pohled na systém z hlediska funkčnosti
- Umožňuje analyzovat a navrhovat statickou strukturu systému
- Pomáhá identifikovat třídy, rozhraní a jejich vztahy
- Slouží k pochopení domény a funkcí, které systém poskytuje
- B. Procesní pohled (Process View):
- Zkoumá chování systému z hlediska běhových procesů a vláken
- Umožňuje identifikovat synchronizační a komunikační aspekty mezi jednotlivými procesy
- Pomáhá zajišťovat škálovatelnost, výkonnost a stabilitu systému
- Slouží k analýze a řešení problémů týkajících se konkurence a distribuce
- C. Fyzický pohled (Physical View):
- Popisuje, jak jsou softwarové komponenty nasazeny na hardwarové prostředky
- Umožňuje řešit otázky týkající se komunikace a propojení mezi hardwarovými jednotkami
- Pomáhá identifikovat potenciální omezení a problémy v hardwarové konfiguraci
- Slouží k optimalizaci nasazení a distribuce systému
- D. Vývojový pohled (Development View):
- Zkoumá strukturu zdrojového kódu, knihoven a modulů
- Umožňuje identifikovat závislosti a propojení mezi jednotlivými částmi kódu
- Pomáhá zlepšovat čitelnost, udržitelnost a modularitu kódu
- Slouží k usnadnění práce vývojářů a podpoře týmové spolupráce
- E. Scénáře (Scenarios):
- Představují konkrétní příklady použití systému (use cases)
- Umožňují ověřit a validovat návrh architektury
- Pomáhají identifikovat problémy a nedostatky v návrhu
- Slouží k provádění průřezů mezi všemi čtyřmi pohledy a k integraci různých aspektů systému
Souvislost mezi 4+1 View Model a UML modely:
UML diagramy pro 4+1 View Model:
- Logický pohled (Logical View):
- Třídní diagram (Class Diagram)
- Objektový diagram (Object Diagram)
- Kompoziční struktura (Composite Structure Diagram)
- Balíčkový diagram (Package Diagram)
- Procesní pohled (Process View):
- Diagram činností (Activity Diagram)
- Sekvenční diagram (Sequence Diagram)
- Diagram spolupráce (Collaboration Diagram)
- Stavový diagram (State Diagram)
- Fyzický pohled (Physical View):
- Diagram nasazení (Deployment Diagram)
- Diagram komponent (Component Diagram)
- Komunikační diagram (Communication Diagram)
- Vývojový pohled (Development View):
- Balíčkový diagram (Package Diagram)
- Diagram komponent (Component Diagram)
Integrace UML s 4+1 View Model:
- UML diagramy poskytují vizuální reprezentaci pro každý pohled v 4+1 View Modelu
- Umožňují efektivní komunikaci mezi architekty, vývojáři, testery a dalšími členy týmu
- Podporují analýzu, návrh, implementaci a údržbu systému
- Usnadňují kontrolu a řízení kvality architektury
Co je softwarová architektura?
- Softwarová architektura je struktura a organizace softwarového systému.
- Zahrnuje komponenty, jejich vlastnosti a vztahy mezi nimi.
- Definuje zásady, směrnice a omezení pro vývoj systému.
Důležitost softwarové architektury při vývoji systému:
- Zajištění kvality:
- Architektura zajišťuje, že systém splňuje funkční a nefunkční požadavky.
- Usnadnění komunikace:
- Architektura slouží jako společný jazyk pro vývojáře, zákazníky a další zúčastněné strany.
- Podpora znovupoužitelnosti:
- Správně navržená architektura umožňuje znovupoužití kódu a komponent.
- Zjednodušení rozhodování:
- Architektura poskytuje rámcové rozhodnutí pro vývojáře, které usnadňuje vývoj a údržbu.
- Řízení rizik:
- Architektura pomáhá identifikovat a řešit rizika spojená s vývojem systému.
- Zlepšení výkonnosti:
- Architektura optimalizuje výkonnost, škálovatelnost a stabilitu systému.
Směrnice pro návrh softwarové architektury:
- Rozdělit a vládnout:
- Systém rozdělit na menší, snadno řiditelné komponenty.
- Abstrakce:
- Použít abstrakce pro zjednodušení složitých problémů.
- Modularita:
- Navrhnout nezávislé a snadno zaměnitelné moduly.
- Zachování informací:
- Minimalizovat závislosti mezi komponentami.
- Škálovatelnost:
- Umožnit snadné rozšíření systému.
- Znovupoužitelnost:
- Navrhovat komponenty tak, aby byly znovupoužitelné.
- Flexibilita:
- Umožnit snadnou údržbu a přizpůsobení změnám požadavků.
Architektonické styly:
- Architektonické styly jsou vzory nebo paradigmata pro návrh softwarové architektury.
Příklad architektonického stylu: MVC (Model-View-Controller)
- Model:
- Reprezentuje data a byznysovou logiku aplikace.
- Nezávislý na prezentační vrstvě a uživatelském rozhraní.
- View (Zobrazení):
- Zodpovědný za prezentaci a zobrazení dat z modelu.
- Aktualizuje se automaticky, když se změní data v modelu.
- Controller (Ovladač):
- Zodpovědný za řízení interakce mezi modelem a zobrazením.
- Zpracovává uživatelské vstupy a aktualizuje model nebo zobrazení.
Detaily architektonického stylu MVC:
- Oddělení zájmů: MVC odděluje zájmy aplikace do tří komponent, což usnadňuje údržbu a rozšíření.
- Znovupoužitelnost: Model a Controller mohou být znovu použity pro různá zobrazení.
- Flexibilita: Změny v jedné komponentě mají minimální dopad na ostatní komponenty.
Co je návrhový vzor (design pattern)?
- Návrhový vzor je opakovatelné řešení pro často se vyskytující problémy v oblasti softwarového návrhu.
- Není to hotový návrh, ale šablona pro řešení problému, kterou lze přizpůsobit konkrétním situacím.
Jaký problém řeší návrhové vzory?
- Návrhové vzory řeší problémy, které se vyskytují opakovaně při návrhu softwarových systémů.
- Pomáhají zlepšit kvalitu kódu, usnadnit komunikaci mezi vývojáři a urychlit vývoj.
Typy návrhových vzorů:
- Vzory pro tvorbu objektů (Creational Patterns):
- Řeší problémy spojené s procesem vytváření objektů.
- Příklady: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
- Strukturální vzory (Structural Patterns):
- Řeší problémy týkající se kompozice tříd a objektů.
- Příklady: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
- Vzory chování (Behavioral Patterns):
- Řeší problémy interakce mezi objekty a způsoby, jakými spolupracují.
- Příklady: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.
Důležitost znalosti návrhových vzorů:
- Zlepšení kvality kódu:
- Návrhové vzory poskytují osvědčené řešení, která zvyšují kvalitu kódu.
- Zvýšení efektivity vývoje:
- Použitím návrhových vzorů lze urychlit vývoj a snížit chybovost.
- Usnadnění komunikace mezi vývojáři:
- Návrhové vzory slouží jako společný jazyk, který usnadňuje komunikaci a porozumění mezi vývojáři.
- Zjednodušení údržby:
- Návrhové vzory usnadňují údržbu a rozšiřování kódu díky jejich známé struktuře a principům.
- Podpora znovupoužitelnosti:
- Návrhové vzory podporují znovupoužitelnost kódu tím, že umožňují snadnější integraci a adaptaci kódu.
Existují návrhové antivzory (design antipatterns)?
- Ano, návrhové antivzory existují.
- Jsou to špatné řešení nebo protipříklady dobrých návrhových vzorů.
- Návrhové antivzory mohou vést ke špatně navrženému, těžko udržitelnému a neefektivnímu kódu.
- Je důležité rozpoznat a vyhýbat se návrhovým antivzorům, aby byla zajištěna dobrá kvalita kódu a efektivní vývoj.
Co je mikroservisní architektura?
- Mikroservisní architektura je přístup k vývoji softwaru, který rozděluje aplikaci na malé, nezávislé služby.
- Tyto služby komunikují pomocí lehkých protokolů (např. REST nebo gRPC) a mají vlastní databáze a konfigurace.
Výhody a nevýhody mikroservisní architektury oproti monolitické architektuře:
Výhody:
- Lehká škálovatelnost:
- Mikroservisy lze škálovat nezávisle na ostatních službách.
- Snadnější údržba:
- Menší a jednodušší kódová základna usnadňuje údržbu a rozšiřování.
- Rychlejší nasazení:
- Mikroservisy lze nasazovat nezávisle, což urychluje vývojový cyklus.
- Technologická agilita:
- Každá služba může používat jiné technologie, což umožňuje snadnější inovace.
- Odolnost vůči chybám:
- Selhání jedné služby má menší dopad na celý systém.
Nevýhody:
- Složitost:
- Větší počet komponent a interakcí mezi nimi zvyšuje složitost systému.
- Výkon:
- Komunikace mezi službami může být pomalejší než u monolitické architektury.
- Správa a monitorování:
- Správa a sledování mnoha nezávislých služeb může být náročné.
- Distribuované transakce:
- Řešení distribuovaných transakcí může být komplikovanější než v monolitických aplikacích.
Jak se vývoj mikroservisů liší od vývoje monolitické aplikace?
- Rozdělení aplikace:
- Aplikace je rozdělena na menší, nezávislé služby.
- Komunikace mezi službami:
- Mikroservisy komunikují pomocí API a lehkých protokolů.
- Databáze a konfigurace:
- Každá služba má vlastní databázi a konfiguraci.
- Nezávislé nasazení:
- Mikroservisy mohou být nasazeny a škálovány nezávisle.
- Technologická diverzita:
- Každá služba může používat jiné technologie, což umožňuje snadnější inovace.
- Správa a monitorování:
- Vyžaduje nástroje a postupy pro správu a sledování mnoha nezávislých služeb.
- Distribuované transakce:
- Řešení distribuovaných transakcí může být komplikovanější než v monolitických aplikacích.
Metodiky, směrnice a osvědčené postupy pro vývoj mikroservisů:
- Rozdělit a vládnout:
- Aplikaci rozdělit na menší, nezávislé a snadno řiditelné služby.
- Definice rozhraní (API):
- Navrhnout jasná a stabilní API pro komunikaci mezi službami.
- Oddělení zájmů:
- Každá služba by měla mít jednu zodpovědnost a řešit jeden aspekt byznysu.
- Decentralizace správy dat:
- Každá služba by měla mít svou vlastní databázi a spravovat svá data nezávisle.
- Stavová nezávislost:
- Preferovat bezestavové služby, které neuchovávají stav mezi požadavky.
- Automatizace nasazení a škálování:
- Používat nástroje a postupy pro automatické nasazení a škálování služeb.
- Monitorování a sledování:
- Implementovat monitorování, sledování a protokolování pro snadnou detekci a řešení problémů.
- Resilience a tolerování selhání:
- Navrhnout služby tak, aby byly schopny zotavit se z chyb a pokračovat v provozu.
- Bezpečnost:
- Zabezpečit komunikaci mezi službami a chránit citlivá data.
- Kontejnerizace a orchestrace:
- Používat kontejnery (např. Docker) a orchestrátory (např. Kubernetes) pro snadnou správu a škálování.
Antivzory, kterým by se mělo vyhnout při vývoji mikroservisů:
- Nedostatečné rozdělení služeb:
- Příliš velké nebo příliš malé služby mohou vést k problémům se škálovatelností a údržbou.
- Nadbytečná komunikace mezi službami:
- Příliš mnoho vzájemné komunikace mezi službami může vést k problémům s výkonem a složitosti.
- Centrální správa dat:
- Spoléhání na jednu centrální databázi pro všechny služby může vést k problémům se škálovatelností a nezávislostí služeb.
- Synchronní komunikace:
- Nadměrné použití synchronní komunikace může způsobit výkonnostní problémy a závislost mezi službami.
- Nedostatečné monitorování a sledování:
- Absence monitorování a sledování může ztížit detekci a řešení problémů.
- Nedostatečná bezpečnost:
- Nedostatek zabezpečení mezi službami nebo nedbalost při ochraně dat může vést k zranitelnostem.
- Vývoj monolitu v mikroservisách:
- Přístup k vývoji mikroservisů, který zachovává špatné návyky z monolitického vývoje, může způsobit výkonnostní a údržbové problémy.
- Nedostatečná automatizace nasazení a škálování:
- Ruční nasazení a škálování služeb může vést k chybám a zpomalit vývoj.
- Zanedbávání kontejnerizace a orchestrace:
- Neužívání kontejnerů a orchestrátorů může ztížit správu a škálování mikroservisů.
- Nedostatečná dokumentace a komunikace:
- Špatně zdokumentované nebo nekomunikované změny mohou vést k nedorozuměním a chybám mezi týmy.
Výběr softwarové architektury
Při výběru softwarové architektury je těžké říci, že jedna architektura je obecně lepší než druhá, protože jejich vhodnost závisí na konkrétních požadavcích a omezeních projektu. Při výběru architektury je důležité zvážit následující faktory:
- Požadavky na výkon:
- Některé architektury mohou lépe podporovat vysoký výkon než jiné, například distribuované systémy pro škálování.
- Škálovatelnost:
- Zvolená architektura by měla umožňovat snadné škálování a rozšiřování aplikace, aby bylo možné lépe řešit růst zátěže.
- Flexibilita a rozšiřitelnost:
- Architektura by měla umožňovat snadné přidávání nových funkcí a integraci s dalšími systémy.
- Bezpečnost:
- Důležité je zvážit, jak dobře architektura řeší bezpečnostní hrozby a zabezpečuje citlivá data.
- Údržba a evoluce:
- Architektura by měla usnadňovat údržbu a umožňovat snadnou adaptaci na změny v požadavcích nebo technologiích.
- Náklady a zdroje:
- Je třeba zohlednit dostupné zdroje, jako je čas, rozpočet a lidské zdroje, a zvážit náklady na vývoj, provoz a údržbu.
- Kompatibilita s technologiemi:
- Zvolená architektura by měla být kompatibilní s technologiemi, které tým již používá, nebo které plánuje použít.
- Týmová zkušenost a dovednosti:
- Je důležité zvážit zkušenosti a dovednosti týmu a jak dobře se dokážou vyrovnat s nároky zvolené architektury.
Při výběru architektury je důležité zvážit všechny tyto faktory a zvolit takovou, která nejlépe vyhovuje konkrétním potřebám a omezením projektu. Není žádná univerzálně “špatná” nebo “lepší” architektura; místo toho je třeba posoudit, jaká architektura je nejvhodnější pro daný projekt.
Měření kvality architektury:
Kvalitu softwarové architektury lze měřit pomocí několika metrik a z různých perspektiv. Některé z těchto perspektiv zahrnují:
- Výkon:
- Měření, jak rychle a efektivně architektura zvládá požadavky, např. doba odezvy, průchodnost a latence.
- Škálovatelnost:
- Hodnocení, jak snadno může architektura růst, aby vyhověla rostoucím požadavkům, a jak dobře se přizpůsobuje změnám v zátěži.
- Flexibilita a rozšiřitelnost:
- Určení, jak snadno může být architektura rozšířena nebo upravena pro nové funkce nebo integraci s dalšími systémy.
- Bezpečnost:
- Hodnocení, jak dobře architektura zabezpečuje citlivá data a chrání před bezpečnostními hrozbami.
- Spolehlivost a odolnost:
- Měření, jak dobře architektura zvládá selhání a chyby, a jak rychle se dokáže zotavit.
- Údržba a evoluce:
- Hodnocení, jak snadno může být architektura udržována a aktualizována, aby vyhovovala změnám v požadavcích a technologiích.
- Modularita a oddělení zájmů:
- Určení, jak dobře je architektura rozdělena do samostatných, snadno spravovatelných a znovupoužitelných komponent.
- Testovatelnost:
- Hodnocení, jak snadno lze architekturu testovat a validovat pro zajištění kvality a spolehlivosti.
Každá z těchto perspektiv nabízí odlišné metriky a hodnocení kvality architektury. Pro měření kvality architektury je třeba zvážit všechny tyto aspekty a určit, jaké metriky jsou nejrelevantnější pro konkrétní projekt a jeho požadavky.
TAL
Topics
Problem/language complexity classes with respect to the time complexity of their solution and memory complexity including undecidable problems/languages. BE4M01TAL (Course web pages)
Questions
Asymptotic growth of functions, time and space complexity of algorithms. Correctness of algorithms - variant and invariant.
Deterministic Turing machines, multitape Turing machines, and Nondeterministic Turing machines.
Decision problems and languages. Complexity classes P, NP, co-NP. Reduction and polynomial reduction, class NPC. Cook theorem. Heuristics and approximate algorithms for solving NP complete problems.
Classes based on space complexity: PSPACE and NPSPACE. Savitch Theorem.
Randomized algorithms. Randomized Turing machines. Classes based on randomization: RP, ZPP, co-RP.
Decidability and undecidability. Recursive and recursively enumerable languages. Diagonal language. Universal language and Universal Turing machine.
ZKS
Topics
The methodology of software testing. Methods for test creation from the application model. Automated testing. BE4M36ZKS (Course web pages)
Questions
- Describe and compare the V and W models of the software testing process. Explain static testing and its role in the W model. Describe individual methods of static testing.
- Explain the principle of Model Based Testing (MBT) and compare its advantages and disadvantages with manual testing approach. Give some examples of models that can be employed in MBT. How does MBT relate to test automation?
- Outline the main test automation principle and economics. What are possible levels at which tests can be automated? Give some examples of main approaches and technologies that can be used in software test automation.
- Explain the equivalence class and boundary values concepts and principle of the Combinatorial Interaction Testing. What is a combinatorial explosion effect, how to effectively reduce the input data combinations? Principle of pairwise (2-way) and N-way testing.
- Principle of path-based testing. Formal definition of system model and test coverage criteria (node/edge coverage, edge-pair coverage, prime-path coverage). How prioritization of process/workflow activities is modelled and handled in the generation of the test cases?
V-model:
- Lineární model
- Testování je prováděno na konci vývojového procesu
- Fáze:
- Analýza požadavků
- Návrh systému
- Návrh architektury
- Návrh komponent
- Implementace
- Integrace
- Testování
- Nasazení
- Nevýhody:
- Méně flexibilní než W-model
- Změny v požadavcích mohou způsobit zpoždění a náklady
W-model:
- Iterativní model
- Testování je prováděno během celého vývojového procesu
- Fáze:
- Analýza požadavků
- Návrh systému
- Návrh architektury
- Návrh komponent
- Implementace
- Integrace
- Testování
- Nasazení
- Výhody:
- Flexibilnější než V-model
- Snadnější detekce a řešení problémů v průběhu vývoje
- Změny v požadavcích méně pravděpodobně způsobí zpoždění a náklady
Srovnání V-modelu a W-modelu:
- V-model je lineární a méně flexibilní
- W-model je iterativní a flexibilnější
- V-model provádí testování až na konci vývoje
- W-model provádí testování během celého vývoje
Statické testování a jeho role ve W-modelu:
Statické testování:
- Testování softwaru bez spuštění kódu
- Zaměřuje se na kontrolu kódu, dokumentace a dalších artefaktů
- Techniky statického testování:
- Průzkum kódu (Code review)
- Statická analýza kódu (Static code analysis)
- Kontrola dokumentace (Documentation review)
- Průzkum návrhu (Design review)
- Kontrola požadavků (Requirements review)
Role ve W-modelu:
- Statické testování je důležitou součástí W-modelu
- Provádí se během celého vývojového procesu, nejen v testovací fázi
- Pomáhá detekovat a řešit problémy v kódu a dokumentaci dříve
- Redukuje riziko chyb a náklady spojené s opravami
- Přispívá k vyšší kvalitě softwaru
Individuální metody statického testování:
- Průzkum kódu (Code review):
- Manuální kontrola zdrojového kódu
- Hledání chyb, nedostatků, či nesouladu se standardy
- Mohou být prováděny kolegy, týmem nebo i autorem kódu (sebereview)
- Statická analýza kódu (Static code analysis):
- Automatická kontrola zdrojového kódu pomocí nástrojů a algoritmů
- Identifikace potenciálních chyb, problémů a nesouladů se standardy
- Příklady nástrojů: FindBugs, PMD, SonarQube, JSHint
- Kontrola dokumentace (Documentation review):
- Manuální kontrola dokumentace projektu
- Ověření správnosti, úplnosti a srozumitelnosti informací
- Zahrnuje kontrolu technické dokumentace, návody, specifikace apod.
- Průzkum návrhu (Design review):
- Manuální kontrola návrhu systému nebo komponenty
- Ověření, zda návrh splňuje požadavky a je vhodný pro implementaci
- Posouzení technických a architektonických rozhodnutí
- Kontrola požadavků (Requirements review):
- Manuální kontrola specifikace požadavků na systém
- Ověření správnosti, úplnosti a srozumitelnosti požadavků
- Hledání možných konfliktů, nejasností nebo nekonzistencí
Manuální testování:
- Testování prováděné lidským testérem
- Testér kontroluje systém nebo aplikaci podle testovacích scénářů
- Zahrnuje funkční, UI a uživatelský zážitek testování
Model Based Testing (MBT):
- Testování založené na modelech
- Vytvoření abstraktního modelu systému nebo aplikace
- Generování testovacích případů z modelu pomocí algoritmů a nástrojů
- Automatická tvorba a provádění testů
Výhody MBT oproti manuálnímu testování:
- Rychlejší generování testovacích případů
- Vyšší pokrytí testů díky systematickému přístupu
- Snížení lidských chyb při tvorbě a provádění testů
- Lehčí aktualizace testů při změnách v systému nebo požadavcích
- Úspora času a nákladů na vývoj
Nevýhody MBT oproti manuálnímu testování:
- Vyšší počáteční náklady na vytvoření a udržbu modelu
- Nutnost specializovaných znalostí a nástrojů pro MBT
- Možné omezení v modelování složitých nebo nestandardních situací
- Menší vhodnost pro testování UI nebo uživatelského zážitku
Příklady modelů použitelných v Model Based Testing (MBT):
- Konečný automat (Finite State Machine, FSM):
- Model založený na stavech a přechodech mezi nimi
- Popisuje chování systému nebo komponenty
- Vhodný pro testování systémů s omezeným počtem stavů a přechodů
- Petriho síť (Petri Net):
- Matematický model pro popis distribuovaných systémů
- Zahrnuje místa, přechody a tokeny pro popis chování
- Použitelný pro testování paralelních nebo konkurenčních systémů
- Markovův řetězec (Markov Chain):
- Model náhodných procesů s konečným počtem stavů
- Přechody mezi stavy závisejí pouze na aktuálním stavu
- Užitečný pro testování systémů s pravděpodobnostními přechody
- Scénářové modely (Scenario Models):
- Modely popisující konkrétní případy užití nebo interakce s aplikací
- Vhodné pro testování funkcionality systému z pohledu uživatele
- Datové modely (Data Models):
- Modely zaměřené na strukturu a vztahy mezi daty v systému
- Použitelné pro testování datových operací, jako je ukládání, načítání a zpracování dat
Vztah MBT k automatickému testování:
- MBT je způsob, jak generovat testovací scénáře a případy z modelů systému
- Automatické testování je proces spouštění těchto testovacích případů bez lidské interakce
- MBT a automatické testování se často používají společně:
- MBT generuje testovací případy
- Automatické testování provádí tyto testovací případy
- Tím se zvyšuje efektivita, rychlost a přesnost testování
Principy automatizace testování:
- Snížení lidského úsilí při provádění testů
- Zvýšení rychlosti a přesnosti testování
- Systematický a konzistentní přístup k testování
- Snížení rizika lidských chyb
- Možnost častějšího a průběžného testování
Ekonomika automatizace testování:
- Vyšší počáteční náklady na nástroje a přípravu testů
- Nižší náklady na provádění testů dlouhodobě
- Snížení nákladů na opravy chyb díky dřívějšímu odhalení
- Rychlejší nasazení a aktualizace softwaru
Úrovně automatizace testů:
- Jednotkové testy (Unit tests):
- Automatické testování jednotlivých funkcí nebo tříd
- Zajišťují, že jednotlivé komponenty fungují správně
- Integrační testy (Integration tests):
- Automatické testování interakce mezi komponentami nebo systémy
- Ověřují, že celý systém funguje správně jako celek
- Systémové testy (System tests):
- Automatické testování celého systému nebo aplikace
- Kontrolují, zda systém splňuje požadavky a očekávání uživatelů
- Uživatelské akceptační testy (User Acceptance tests, UAT):
- Částečně automatizované testování z pohledu uživatele a jeho zkušeností
- Ověřují, že aplikace je připravena k nasazení a použití
- Regresní testy (Regression tests):
- Automatické testování zaměřené na odhalení chyb po změnách v kódu
- Kontrolují, že nové změny nezpůsobily problémy v již otestovaných částech
Příklady hlavních přístupů a technologií používaných v automatizaci testování softwaru:
- Nástroje pro jednotkové testování (Unit testing tools):
- JUnit (pro Java)
- NUnit (pro .NET)
- Mocha (pro JavaScript)
- Pytest (pro Python)
- Pomáhají vytvářet a provádět jednotkové testy pro jednotlivé komponenty
- Nástroje pro integrační a systémové testování (Integration and
system testing tools):
- Selenium (pro webové aplikace)
- Appium (pro mobilní aplikace)
- JMeter (pro testování výkonnosti)
- SoapUI (pro testování webových služeb)
- Umožňují automatizaci testů na úrovni celého systému nebo aplikace
- Rámce pro Behavior-Driven Development (BDD):
- Cucumber (pro Ruby, Java, .NET)
- SpecFlow (pro .NET)
- Behave (pro Python)
- Pomáhají vytvářet testy založené na chování systému a propojení s požadavky
- Nástroje pro kontinuální integraci (Continuous Integration, CI) a
kontinuální nasazení (Continuous Deployment, CD):
- Jenkins
- GitLab CI/CD
- Bamboo
- CircleCI
- Travis CI
- Umožňují automatizovat provádění testů a nasazení aplikace v průběhu vývoje
- Testovací nástroje pro vizuální porovnávání (Visual testing tools):
- Applitools
- Percy
- Galen Framework
- Porovnávají vizuální vzhled aplikace napříč různými prohlížeči, platformami a obrazovkami
- Nástroje pro nahrávání a přehrávání testů (Record and playback
tools):
- Selenium IDE
- Katalon Studio
- Umožňují nahrát testovací scénáře při manuálním provádění testu a poté je automaticky přehrát
Ekvivalentní třída (Equivalence Class):
- Koncept založený na rozdělení vstupních hodnot do skupin, které vykazují podobné chování
- Každá skupina se nazývá ekvivalentní třída
- Testování se provádí na základě reprezentativního vzorku hodnot z každé třídy
- Účinně snižuje počet testovacích případů, aniž by se snížila účinnost testování
Hraniční hodnoty (Boundary Values):
- Koncept zaměřený na testování hodnot na hranicích ekvivalentních tříd
- Hraniční hodnoty často zahrnují:
- Minimální a maximální hodnoty
- Hodnoty těsně nad a pod minimálními a maximálními hodnotami
- Testování hraničních hodnot je založeno na pozorování, že chyby se často vyskytují u hranic ekvivalentních tříd
Kombinatorické interakční testování (Combinatorial Interaction Testing):
- Princip spočívá v testování všech možných kombinací dvou nebo více proměnných
- Zaměřuje se na odhalování chyb způsobených nečekanými interakcemi mezi proměnnými
- Kombinatorické testování může být prováděno pomocí různých technik,
jako je:
- Pairwise testing (testování všech možných dvojic proměnných)
- Orthogonal arrays (testování s omezeným počtem kombinací, které zahrnují všechny možné interakce)
- Účinně snižuje počet testovacích případů, aniž by se snížila účinnost testování
Kombinatorický výbuch (Combinatorial Explosion):
- Efekt, kdy počet kombinací vstupních dat rychle roste s přibývajícím počtem proměnných nebo hodnot
- Výsledkem je velký počet testovacích případů, což zvyšuje nároky na čas a zdroje při testování
Jak efektivně snížit kombinace vstupních dat:
- Pairwise testing (dvojice testů):
- Testování všech možných dvojic proměnných místo všech kombinací
- Značně snižuje počet testovacích případů, aniž by se značně snížila účinnost testování
- Orthogonal Arrays (ortogonální pole):
- Testování s omezeným počtem kombinací, které zahrnují všechny možné interakce mezi proměnnými
- Pomáhá snížit počet testovacích případů, zatímco zachovává dobré pokrytí interakcí
- Testování založené na prioritách:
- Prioritizace testovacích případů na základě rizik a pravděpodobnosti chyb
- Provedení testů s vyšší prioritou a omezení testů s nižší prioritou
- Ekvivalentní třídy (Equivalence Classes) a hraniční hodnoty
(Boundary Values):
- Rozdělení vstupních hodnot do ekvivalentních tříd a testování na základě reprezentativního vzorku
- Testování hraničních hodnot, které se zaměřuje na hodnoty na hranicích tříd
- Model-Based Testing (MBT):
- Vytvoření matematického nebo formálního modelu systému a generování testovacích případů z tohoto modelu
- Pomáhá snížit počet testovacích případů a současně zvyšuje účinnost testování
Pairwise (2-way) testing:
- Pairwise testing je technika kombinatorického testování, která zkoumá interakce mezi dvojicemi proměnných
- Místo testování všech možných kombinací proměnných se zaměřuje na testování všech dvojic proměnných
- Vychází z předpokladu, že většina chyb je způsobena interakcemi mezi jednotlivými páry proměnných
- Pairwise testing značně snižuje počet testovacích případů, aniž by se značně snížila účinnost testování
- Nástroje, jako jsou AllPairs, PICT nebo Hexawise, mohou být použity pro generování pairwise testovacích případů
N-way testing:
- N-way testing je rozšířením pairwise testingu, které zkoumá interakce mezi N proměnnými
- Pro N > 2 se zvyšuje pokrytí interakcí mezi proměnnými, ale roste také počet testovacích případů
- N-way testing může být užitečné pro systémy s vyšší mírou komplexnosti nebo vyšším rizikem chyb způsobených interakcemi mezi více proměnnými
- Volba hodnoty N závisí na rovnováze mezi potřebou pokrytí interakcí a omezením počtu testovacích případů
- Nástroje, jako jsou AllPairs, PICT nebo Hexawise, mohou být také použity pro generování N-way testovacích případů s různými hodnotami
Princip testování založeného na cestách (Path-based testing):
- Testování založené na cestách je technika, která se zaměřuje na zkoumání různých cest (paths) v systému nebo algoritmu
- Cesty jsou sledy uzlů (nodes) a hran (edges) v grafu reprezentujícím systém nebo algoritmus
- Tato metoda se často používá při testování řídicích struktur kódu, jako jsou podmínky, cykly a větvení
- Cílem je identifikovat a otestovat všechny možné cesty, aby se maximalizovala účinnost testování a odhalily chyby v kódu
Formální definice modelu systému a kritéria pokrytí testů:
- Node (uzel) coverage:
- Požadavek, aby každý uzel v grafu byl navštíven alespoň jednou během testování
- Zaměřuje se na procházení všech možných stavů systému
- Méně náročné než ostatní kritéria pokrytí, ale méně účinné v odhalování chyb
- Edge (hrana) coverage:
- Požadavek, aby každá hrana v grafu byla projita alespoň jednou během testování
- Zaměřuje se na testování všech možných přechodů mezi uzly
- Přináší lepší pokrytí než node coverage, ale vyšší nároky na testovací případy
- Edge-pair coverage:
- Požadavek, aby každá dvojice sousedních hran v grafu byla projita alespoň jednou během testování
- Zaměřuje se na testování všech možných sekvencí dvou přechodů mezi uzly
- Poskytuje ještě lepší pokrytí než edge coverage, ale s vyššími nároky na testovací případy
- Prime-path coverage:
- Požadavek, aby každá jedinečná, nezkrácená cesta v grafu byla projita alespoň jednou během testování
- Zaměřuje se na testování všech možných sledů uzlů a hran bez opakování
- Poskytuje nejlepší pokrytí v porovnání s ostatními kritérii, ale s nejvyššími nároky na testovací případy
Prioritizace procesů/workflow aktivit při generování testovacích případů:
- Analýza rizik:
- Identifikace oblastí s nejvyšším rizikem chyb nebo dopadů na systém
- Prioritizace testování těchto oblastí s vyšším rizikem
- Pomáhá alokovat zdroje na nejvíce kritické části systému
- Důležitost funkcí:
- Určení důležitosti jednotlivých funkcí nebo workflow aktivit pro uživatele nebo systém
- Testování nejdůležitějších funkcí má vyšší prioritu
- Zajišťuje, že klíčové části systému jsou pečlivě testovány
- Frekvence použití:
- Identifikace často používaných funkcí nebo workflow aktivit
- Prioritizace testování těchto často používaných částí
- Alokace zdrojů na oblasti, které mají největší dopad na uživatele
- Historie chyb:
- Analýza předchozích chyb a identifikace oblastí, které jsou náchylnější k chybám
- Prioritizace testování těchto částí systému
- Zaměření na odhalení a opravu chyb v problémových oblastech
- Závislosti mezi komponentami:
- Identifikace komponent nebo workflow aktivit, které mají významné závislosti na ostatních částech systému
- Prioritizace testování těchto závislých částí
- Odhalení chyb v závislých komponentách, které by mohly ovlivnit celý systém
- Testovací techniky a kritéria pokrytí:
- Použití různých testovacích technik, jako jsou ekvivalentní třídy, hraniční hodnoty, kombinatorické testování nebo testování založené na cestách
- Určení kritérií pokrytí pro testování, jako je node coverage, edge coverage, edge-pair coverage nebo prime-path coverage
- Prioritizace testovacích případů na základě zvolených technik a kritérií pokrytí
Při generování testovacích případů se prioritizace provádí na základě různých faktorů, jako je riziko, důležitost funkcí, frekvence použití, historie chyb, závislosti mezi komponentami a zvolené testovací techniky a kritéria pokrytí. Prioritizace pomáhá alokovat zdroje na nejdůležitější části systému a maximalizovat účinnost testování.