<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://ccwiki.digitalcampusvorarlberg.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=192.168.0.0%2F16</id>
	<title>CCWiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://ccwiki.digitalcampusvorarlberg.at/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=192.168.0.0%2F16"/>
	<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php/Spezial:Beitr%C3%A4ge/192.168.0.0/16"/>
	<updated>2026-08-25T22:22:25Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=UML_Klassendiagramm&amp;diff=144</id>
		<title>UML Klassendiagramm</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=UML_Klassendiagramm&amp;diff=144"/>
		<updated>2021-01-07T17:16:56Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: Die Seite wurde neu angelegt: „TODO: * Was ist ein Klassendiagramm? * Wozu wird es benötigt? * Welche Elemente gibt es? Erkläre dies so detailliert und anschaulich wie möglich * Stelle in…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO:&lt;br /&gt;
* Was ist ein Klassendiagramm?&lt;br /&gt;
* Wozu wird es benötigt?&lt;br /&gt;
* Welche Elemente gibt es? Erkläre dies so detailliert und anschaulich wie möglich&lt;br /&gt;
* Stelle in einem anschaulichen Beispiel ein Klassendiagramm Code gegenüber&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=143</id>
		<title>Objektorientiertes Design und UML</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=143"/>
		<updated>2021-01-07T17:13:55Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden wird zuerst auf die Begriffe &#039;&#039;&#039;UML&#039;&#039;&#039; und &#039;&#039;&#039;modellieren&#039;&#039;&#039; eingegangen. In weiterer Folge werden wir uns mit zwei gebräuchlichen Diagrammtypen, dem &#039;&#039;&#039;Klassendiagramm&#039;&#039;&#039; und dem &#039;&#039;&#039;Sequenzdiagramm&#039;&#039;&#039; beschäftigen.&lt;br /&gt;
= Modellieren =&lt;br /&gt;
TODO: Hier soll beschrieben werden was &#039;&#039;&#039;modellieren&#039;&#039;&#039; im allgemeinen und dann speziell in der Softwareentwicklung bedeutet.&lt;br /&gt;
= UML =&lt;br /&gt;
TODO: Hier soll geklärt werden was UML ist, von der Begriffsbedeutung bis hin zu den Einsatzgebieten in der Softwareentwicklung. Weiters sollen alle Diagrammtypen und deren Einteilung in Kategorien schön dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
== Diagramme ==&lt;br /&gt;
[[UML_Klassendiagramm|UML Klassendiagramm]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[UML_Sequenzdiagramm|UML Sequenzdiagramm]]&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=142</id>
		<title>Objektorientiertes Design und UML</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=142"/>
		<updated>2021-01-07T17:12:30Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Diagramme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zuerst sollen die Bregiffe &#039;&#039;&#039;UML&#039;&#039;&#039; und &#039;&#039;&#039;modellieren&#039;&#039;&#039; geklärt werden.&lt;br /&gt;
= Modellieren =&lt;br /&gt;
TODO: Hier soll beschrieben werden was &#039;&#039;&#039;modellieren&#039;&#039;&#039; im allgemeinen und dann speziell in der Softwareentwicklung bedeutet.&lt;br /&gt;
= UML =&lt;br /&gt;
TODO: Hier soll geklärt werden was UML ist, von der Begriffsbedeutung bis hin zu den Einsatzgebieten in der Softwareentwicklung. Weiters sollen alle Diagrammtypen und deren Einteilung in Kategorien schön dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
== Diagramme ==&lt;br /&gt;
[[UML_Klassendiagramm|UML Klassendiagramm]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[UML_Sequenzdiagramm|UML Sequenzdiagramm]]&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=141</id>
		<title>Objektorientiertes Design und UML</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=141"/>
		<updated>2021-01-07T17:12:20Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zuerst sollen die Bregiffe &#039;&#039;&#039;UML&#039;&#039;&#039; und &#039;&#039;&#039;modellieren&#039;&#039;&#039; geklärt werden.&lt;br /&gt;
= Modellieren =&lt;br /&gt;
TODO: Hier soll beschrieben werden was &#039;&#039;&#039;modellieren&#039;&#039;&#039; im allgemeinen und dann speziell in der Softwareentwicklung bedeutet.&lt;br /&gt;
= UML =&lt;br /&gt;
TODO: Hier soll geklärt werden was UML ist, von der Begriffsbedeutung bis hin zu den Einsatzgebieten in der Softwareentwicklung. Weiters sollen alle Diagrammtypen und deren Einteilung in Kategorien schön dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
== Diagramme ==&lt;br /&gt;
[[UML_Klassendiagramm|UML Klassendiagramm]]&lt;br /&gt;
[[UML_Sequenzdiagramm|UML Sequenzdiagramm]]&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=140</id>
		<title>Objektorientiertes Design und UML</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Objektorientiertes_Design_und_UML&amp;diff=140"/>
		<updated>2021-01-07T17:05:19Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: Leere Seite erstellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=136</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=136"/>
		<updated>2021-01-07T16:58:32Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Einheitliche Schnittstelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es ist vielmehr ein Architekturstil dem gefolgt werden soll dieser besteht aus Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen. Die einheitliche Schnittstelle besteht aus vier weiteren Eigenschaften, wobei wir im folgenden nur drei besprechen werden. Das Ziel ist, wie der Name schon sagt, eine einheitliche Schnittstelle für Webservices und eine daraus folgende einfache Nutzbarkeit. (HATEOS lassen wir außen vor, wenn dies auch laut Fielding die wichtigste Eigenschaft ist.)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist. Diese Ressourcen können einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Mögliche Implementierung ====&lt;br /&gt;
In modernen Technologien wie z.B.: Express für Node.js finden sich automatische mechanismen für die Caching implementierung über ETags. Der Ablauf ist denkbar einfach. Der Server betrachtet vor dem Absenden der Antwort an den Client deren Inhalt. Es geht hier nur um den HTTP Body, die Header spielen hier keine Rolle. Aus dem Body wird eine Hashsumme berechnet und diese wird dann als &#039;&#039;ETag&#039;&#039; verwendet.&lt;br /&gt;
 &#039;&#039;&#039;Hashsumme:&#039;&#039;&#039; Mittels eines Hashalgorithmus wie z.b.: (SHA256, MD5, ...) kann aus einer großen Datenmenge ein &amp;quot;eindeutiger&amp;quot; Wert berechnet werden. Bei SHA256 hat dieser Wert &#039;&#039;&#039;immer&#039;&#039;&#039; eine Länge von 256 Bit, egal wie groß der Input ist. Der Wert kann natürlich nicht eindeut sein, doch die Chance ist verschwindend gering, dass für unterschiedliche Input Daten, die selbe Hashsumme gebildet wird.&lt;br /&gt;
Diese Implementierung bietet eine einfache Möglichkeit des Cachings um die Datenübertragung vom Client zum Server deutlich zu reduzieren. Dies reduziert die Netzwerklast auf Client und Serverseite.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Eine Rechenauslastung auf Seiten des Servers findet jedoch nicht statt. Der Body der Antwort muss bei jeder Antwort erstellt werden um den &#039;&#039;ETag&#039;&#039; zu generieren. Das bedeutet, der Server muss trotzdem Anfragen an die Datenbank stellen bzw. alle nötigen Berechnungen ausführen um die Antwort zu erstellen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Weiters ist das Bilden der Hashsumme, vorallem wenn es sich um größere Datenmengen handelt, eine Rechenintensive Operation. Ändern sich die Daten regelmäßig, so könnte man sich das bilden der Hashsumme und den daraus resultierenden mehraufwand, sparen.&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=135</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=135"/>
		<updated>2021-01-07T11:42:25Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* RESTful Webservice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es ist vielmehr ein Architekturstil dem gefolgt werden soll dieser besteht aus Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Mögliche Implementierung ====&lt;br /&gt;
In modernen Technologien wie z.B.: Express für Node.js finden sich automatische mechanismen für die Caching implementierung über ETags. Der Ablauf ist denkbar einfach. Der Server betrachtet vor dem Absenden der Antwort an den Client deren Inhalt. Es geht hier nur um den HTTP Body, die Header spielen hier keine Rolle. Aus dem Body wird eine Hashsumme berechnet und diese wird dann als &#039;&#039;ETag&#039;&#039; verwendet.&lt;br /&gt;
 &#039;&#039;&#039;Hashsumme:&#039;&#039;&#039; Mittels eines Hashalgorithmus wie z.b.: (SHA256, MD5, ...) kann aus einer großen Datenmenge ein &amp;quot;eindeutiger&amp;quot; Wert berechnet werden. Bei SHA256 hat dieser Wert &#039;&#039;&#039;immer&#039;&#039;&#039; eine Länge von 256 Bit, egal wie groß der Input ist. Der Wert kann natürlich nicht eindeut sein, doch die Chance ist verschwindend gering, dass für unterschiedliche Input Daten, die selbe Hashsumme gebildet wird.&lt;br /&gt;
Diese Implementierung bietet eine einfache Möglichkeit des Cachings um die Datenübertragung vom Client zum Server deutlich zu reduzieren. Dies reduziert die Netzwerklast auf Client und Serverseite.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Eine Rechenauslastung auf Seiten des Servers findet jedoch nicht statt. Der Body der Antwort muss bei jeder Antwort erstellt werden um den &#039;&#039;ETag&#039;&#039; zu generieren. Das bedeutet, der Server muss trotzdem Anfragen an die Datenbank stellen bzw. alle nötigen Berechnungen ausführen um die Antwort zu erstellen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Weiters ist das Bilden der Hashsumme, vorallem wenn es sich um größere Datenmengen handelt, eine Rechenintensive Operation. Ändern sich die Daten regelmäßig, so könnte man sich das bilden der Hashsumme und den daraus resultierenden mehraufwand, sparen.&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=134</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=134"/>
		<updated>2021-01-07T11:03:29Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Mögliche Implementierung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Mögliche Implementierung ====&lt;br /&gt;
In modernen Technologien wie z.B.: Express für Node.js finden sich automatische mechanismen für die Caching implementierung über ETags. Der Ablauf ist denkbar einfach. Der Server betrachtet vor dem Absenden der Antwort an den Client deren Inhalt. Es geht hier nur um den HTTP Body, die Header spielen hier keine Rolle. Aus dem Body wird eine Hashsumme berechnet und diese wird dann als &#039;&#039;ETag&#039;&#039; verwendet.&lt;br /&gt;
 &#039;&#039;&#039;Hashsumme:&#039;&#039;&#039; Mittels eines Hashalgorithmus wie z.b.: (SHA256, MD5, ...) kann aus einer großen Datenmenge ein &amp;quot;eindeutiger&amp;quot; Wert berechnet werden. Bei SHA256 hat dieser Wert &#039;&#039;&#039;immer&#039;&#039;&#039; eine Länge von 256 Bit, egal wie groß der Input ist. Der Wert kann natürlich nicht eindeut sein, doch die Chance ist verschwindend gering, dass für unterschiedliche Input Daten, die selbe Hashsumme gebildet wird.&lt;br /&gt;
Diese Implementierung bietet eine einfache Möglichkeit des Cachings um die Datenübertragung vom Client zum Server deutlich zu reduzieren. Dies reduziert die Netzwerklast auf Client und Serverseite.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Eine Rechenauslastung auf Seiten des Servers findet jedoch nicht statt. Der Body der Antwort muss bei jeder Antwort erstellt werden um den &#039;&#039;ETag&#039;&#039; zu generieren. Das bedeutet, der Server muss trotzdem Anfragen an die Datenbank stellen bzw. alle nötigen Berechnungen ausführen um die Antwort zu erstellen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Weiters ist das Bilden der Hashsumme, vorallem wenn es sich um größere Datenmengen handelt, eine Rechenintensive Operation. Ändern sich die Daten regelmäßig, so könnte man sich das bilden der Hashsumme und den daraus resultierenden mehraufwand, sparen.&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=133</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=133"/>
		<updated>2021-01-07T10:59:06Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Mögliche Implementierung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Mögliche Implementierung ====&lt;br /&gt;
In modernen Technologien wie z.B.: Express für Node.js finden sich automatische mechanismen für die Caching implementierung über ETags. Der Ablauf ist denkbar einfach. Der Server betrachtet vor dem Absenden der Antwort an den Client deren Inhalt. Es geht hier nur um den HTTP Body, die Header spielen hier keine Rolle. Aus dem Body wird eine Hashsumme berechnet und diese wird dann als &#039;&#039;ETag&#039;&#039; verwendet.&lt;br /&gt;
 &#039;&#039;&#039;Hashsumme:&#039;&#039;&#039; Mittels eines Hashalgorithmus wie z.b.: (SHA256, MD5, ...) kann aus einer großen Datenmenge ein &amp;quot;eindeutiger&amp;quot; Wert berechnet werden. Bei SHA256 hat dieser Wert &#039;&#039;&#039;immer&#039;&#039;&#039; eine Länge von 256 Bit, egal wie groß der Input ist. Der Wert kann natürlich nicht eindeut sein, doch die Chance ist verschwindend gering, dass für unterschiedliche Input Daten, die selbe Hashsumme gebildet wird.&lt;br /&gt;
Diese Implementierung bietet eine einfache Möglichkeit des Cachings um die Datenübertragung vom Client zum Server deutlich zu reduzieren. Die Reduziert die Netzwerklast auf Client und Serverseite.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Eine Rechenauslastung auf Seiten des Servers findet jedoch nicht statt. Der Body der Antwort muss bei jeder Antwort erstellt werden um den &#039;&#039;ETag&#039;&#039; zu erstellen. Das bedeutet, der Server muss trotzdem Anfragen an die Datenbank stellen bzw. alle nötigen Berechnungen ausführen um die Antwort zu erstellen.&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=132</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=132"/>
		<updated>2021-01-07T10:57:06Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Mögliche Implementierung ====&lt;br /&gt;
In modernen Technologien wie z.B.: Express für Node.js finden sich automatische mechanismen für die Caching implementierung über ETags. Der Ablauf ist denkbar einfach. Der Server betrachtet vor dem Absenden der Antwort an den Client deren Inhalt. Es geht hier nur um den HTTP Body, die Header spielen hier keine Rolle. Aus dem Body wird eine Hashsumme berechnet und diese wird dann als &#039;&#039;ETag&#039;&#039; verwendet.&lt;br /&gt;
 &#039;&#039;&#039;Hashsumme:&#039;&#039;&#039; Mittels eines Hashalgorithmus wie z.b.: (SHA256, MD5, ...) kann aus einer großen Datenmenge ein &amp;quot;eindeutiger&amp;quot; Wert berechnet werden. Bei SHA256 hat dieser Wert &#039;&#039;&#039;immer&#039;&#039;&#039; eine Länge von 256 Bit, egal wie groß der Input ist. Der Wert kann natürlich nicht eindeut sein, doch die Chance ist verschwindend gering, dass für unterschiedliche Input Daten, die selbe Hashsumme gebildet wird.&lt;br /&gt;
Diese Implementierung bietet eine einfache Möglichkeit des Cachings um die Datenübertragung vom Client zum Server deutlich zu reduzieren. Der Body der Antwort muss ebenfalls bei jeder Antwort erstellt werden. Das bedeutet, der Server muss trotzdem Anfragen an die Datenbank stellen bzw. alles nötige um die Antwort zu erstellen muss erledigt werden.&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=131</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=131"/>
		<updated>2021-01-07T10:37:33Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=130</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=130"/>
		<updated>2021-01-07T10:37:10Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
 HTTP Caching soll implementiert werden. Wobei jede Anfrage die nicht gestellt werden muss, die beste ist.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;497fb2348f705&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke1&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Zu einem späteren Zeitpunkt holt der Client erneut die Selbe Ressource und sendet wieder den &#039;&#039;ETag&#039;&#039; mit. Die Ressource hat sich jedoch am Server geändert. Dieser sendet die Ressource dem Client zurück und sendet zusätzlich im Header den neuen &#039;&#039;ETag&#039;&#039; mit. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=129</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=129"/>
		<updated>2021-01-07T10:31:56Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=128</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=128"/>
		<updated>2021-01-07T10:31:47Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll sie nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
 Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=127</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=127"/>
		<updated>2021-01-07T10:31:14Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll diese nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In folgender Tabelle wird die Funktionsweise von HTTP Caching mittels ETag beschrieben. Man beachte, die HTTP Anfragen sind &#039;&#039;nicht&#039;&#039; vollständig und beschränken sich auf die fürs Caching wesentlichen Header.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=126</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=126"/>
		<updated>2021-01-07T10:30:08Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll diese nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Funktionsweise von HTTP Caching mittels ETag:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header. Man könnte diese Anfrage wie folgt interpretieren: Gib mir die Ressource nur zurück, wenn der &#039;&#039;ETag&#039;&#039; nicht  mehr zutrifft. Der Server Antwortet mit dem &#039;&#039;HTTP Statuscode 304 Not Modified&#039;&#039;. Dies bedeutet, es hat sich nichts geändert. Der Client wird somit darauf hingewiesen die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=125</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=125"/>
		<updated>2021-01-07T10:28:03Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Caching */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll diese nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Funktionsweise von HTTP Caching mittels ETag:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header (gib es nur zurück, wenn sich was geändert hat). Der Server Antwortet mit dem HTTP Statuscode 304. Dies bedeutet, es hat sich nichts geändert und weist den Client somit an, die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=124</id>
		<title>Webservices und Client Server Konzepte</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Webservices_und_Client_Server_Konzepte&amp;diff=124"/>
		<updated>2021-01-07T10:17:11Z</updated>

		<summary type="html">&lt;p&gt;192.168.192.1: /* Addressierbarkeit von Ressourcen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Zu allererst soll geklärt werden, was ein Webservices ist:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Ein Webservice (auch Webdienst) stellt eine Schnittstelle für die Maschine-zu-Maschine- oder Anwendungs-Kommunikation über Rechnernetze wie das Internet zur Verfügung. Dabei werden Daten ausgetauscht und auf entfernten Computern (Servern) Funktionen aufgerufen. Jeder Webservice besitzt einen Uniform Resource Identifier (URI), über den er eindeutig identifizierbar ist, sowie je nach Implementierung eine Schnittstellenbeschreibung in maschinenlesbarem Format (als XML-Artefakt, z. B. WSDL), die definiert, wie mit dem Webservice zu interagieren ist. Die Kommunikation kann über Protokolle aus dem Internetkontext wie HTTP oder HTTPS erfolgen; über diese Protokolle wiederum kann beispielsweise XML oder JSON übertragen werden. Ein Webservice ist plattformunabhängig und steht in der Regel mehreren Programmen zum Aufrufen bereit. [https://de.wikipedia.org/wiki/Webservice]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Was bedeutet dies nun ganz stark vereinfacht. Ein Webservice ist ein Programm, welches auf einem Server läuft, der über das Internet erreichbar ist. Ein Client (Browser, Anwendung, App), sendet Anfragen an diesen Webservice mit einem standardisierten Protokoll (z.B.: HTTP) und erhält darauf Antworten.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden wollen wir uns nun mit RESTful Webservices beschäftigen, diese erfreuen sich großer beliebtheit und stehen in Konkurrenz zu anderen Varianten wie z.b.:&lt;br /&gt;
* &#039;&#039;WSDL/Soap basierten Webservices&#039;&#039; - Stark antiquiertes Konezpt&lt;br /&gt;
* &#039;&#039;GraphQL basierten Webservices&#039;&#039; - Damit werden unzulänglichkeiten bei RESTful Webservices behoben, jedoch wird auch auf die einheitliche Schnittstelle verzichtet&lt;br /&gt;
&lt;br /&gt;
= RESTful Webservice =&lt;br /&gt;
Ein RESTful Webservice ist nicht eine konkrete Implementierung, es sind vielmehr Prinzipien und Eigenschaften die auf einen Webservice zutreffen müssen, damit es sich um einen RESTful Webservice handelt bzw. einen Webservice der auf den REST Prinzipien beruht. REST steht für &#039;&#039;&#039;Represential State Transfer&#039;&#039;&#039; und wurde von Roy Fielding &amp;quot;entwickelt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien ==&lt;br /&gt;
Im folgenden wollen wir auf einige der Prinzipien eingehen. Folgender Abschnitt ist jedoch nicht vollständig, soll aber an dieser Stelle ausreichen.&lt;br /&gt;
&lt;br /&gt;
=== Einheitliche Schnittstelle ===&lt;br /&gt;
Dies ist ein Hauptunterscheidungsmerkmal zu den meisten anderen Webservice Architekturen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wir sprechen hier von Ressourcen die einheitlich manipuliert, abgerufen und identifiziert werden können. Eine Ressource kann z.B. ein Kundenprofil sein.&lt;br /&gt;
==== Addressierbarkeit von Ressourcen ====&lt;br /&gt;
Jede Ressource hat einen eindeutigen Bezeichner und ist über eine URL erreichbar ist&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 Kunde mit der id 101 -&amp;gt; https://webservice.drlue.at/customer/101&lt;br /&gt;
&lt;br /&gt;
==== Selbstbeschreibende Nachrichten ====&lt;br /&gt;
REST Nachrichten sollen selbstbeschreibend sein, dafür sollen Standardmethoden verwendet werden, meist werden hier die HTTP Methoden verwendet.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Betrachten wir das Beispiel des Kunden mit der Id 101 und stellen den Vergleich zu den HTTP Methoden her:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP Methode !! URL !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| GET || https://webservice.drlue.at/customer/101 || Holen der Benutzerinformation&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || https://webservice.drlue.at/customer/101 || Löschen des Benutzers&lt;br /&gt;
|-&lt;br /&gt;
| PUT || https://webservice.drlue.at/customer/101 || Verändern des Benutzers, es müssen die zu ändernden Daten mitgesendet werden&lt;br /&gt;
|-&lt;br /&gt;
| POST || https://webservice.drlue.at/customer || Anlegen eines neuen Benutzers, die Benutzerdaten müssen mitgesendet werden&lt;br /&gt;
|}&lt;br /&gt;
=== Caching ===&lt;br /&gt;
HTTP Caching soll implementiert werden.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Klären wir zuerst den Begriff des Cachings. Dieses Konzept gilt natürlich in vielen Bereichen der Informatik, wir erklären den Begriff anhand des Zugriffs auf eine Ressource. Eine Ressource wird geholt, zu einem späteren Zeitpunkt wird diese Ressource erneut geholt. Hat sich diese nicht verändert, so soll diese nicht erneut übertragen werden, sondern aus dem Zwischenspeicher der Anwendung abgerufen werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Durch Caching bei Webanwendungen soll die Übertragung von Daten über das Internet reduziert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Funktionsweise von HTTP Caching mittels ETag:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Ablauf beim Anfragen auf eine Ressource (http://webservice.drlue.at/customer/101)&lt;br /&gt;
|-&lt;br /&gt;
! Anfrage !! Antwort !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;luke&amp;quot;,&lt;br /&gt;
  &amp;quot;id&amp;quot;: 101&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Erstmaliges holen der spezifischen Ressource. Server Antwortet mit den Daten und liefert im HTTP Header den &#039;&#039;ETag&#039;&#039; mit&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
GET /customer/101 HTTP/1.1&lt;br /&gt;
Host: webservice.drlue.at&lt;br /&gt;
If-none-match: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|style=&amp;quot;white-space: nowrap;&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;http&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
HTTP/1.1 304 Not Modified&lt;br /&gt;
Etag: &amp;quot;478fb2348f700&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Eine weitere Anfrage des Clients erfolgt mit dem &#039;&#039;ETag&#039;&#039; nun aber im &#039;&#039;If-none-match&#039;&#039; Header (gib es nur zurück, wenn sich was geändert hat). Der Server Antwortet mit dem HTTP Statuscode 304. Dies bedeutet, es hat sich nichts geändert und weist den Client somit an, die Daten aus seinem eigenen &#039;&#039;Cache&#039;&#039; oder &#039;&#039;Zwischenspeicher&#039;&#039; zu holen. &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| Beispiel || Beispiel || Beispiel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Zustandslosigkeit ===&lt;/div&gt;</summary>
		<author><name>192.168.192.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=80</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=80"/>
		<updated>2021-01-06T09:04:13Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Code beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln. Um das Grenzverhalten eines Algorithmus zu betrachten, analysieren wir wieviele Operationen im schlechtesten Fall im bezug auf die größe des Problems (z.B.: Anzahl der Elemente) benötigt werden. Konstante Werte können dabei vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Suchen des kleinsten und größten Elements in einem Array.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 2 || 3 || 4 || 5 || 6&lt;br /&gt;
|}&lt;br /&gt;
Um das größte Element zu finden, werden 5 Schritte benötigt, dies entspricht der Länge des Arrays - 1. Für die Suche des größten Elements benötigen wir ebenfalls 5 Schritte. Somit ist die Laufzeit für unseren Algorithmus &#039;&#039;&#039;2 * (n - 1)&#039;&#039;&#039;, die Konstanten werden entfernt: &#039;&#039;&#039;O(n)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void findMinAndMax(int[] arr) {&lt;br /&gt;
  int min = arr[0];&lt;br /&gt;
  int max = arr[0];&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    min = Math.min(min, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    max = Math.max(max, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  System.out.println(&amp;quot;Min: &amp;quot;+min);&lt;br /&gt;
  System.out.println(&amp;quot;Max: &amp;quot;+max);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code Beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public int get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
  return current.getValue();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
== Bäume ==&lt;br /&gt;
Bäume sind Datenstrukturen, welche im Kontext von Suchstrukturen, automatisch einer gewissen Ordnung folgen. Bereits nach dem Einfügen sind diese Element sortiert.&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
Sortierte Ausgabe eines binären Suchbaums (In-Order)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void print(NOde node) {&lt;br /&gt;
  if(node == null) {&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  //Rekursiver aufruf für den Linken Teilbaum&lt;br /&gt;
  print(node.getLeft());&lt;br /&gt;
  System.out.print(&amp;quot; &amp;quot;+node.getValue()+&amp;quot; &amp;quot;);&lt;br /&gt;
  print(node.getRight());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=79</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=79"/>
		<updated>2021-01-06T09:03:25Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Datenstrukturen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln. Um das Grenzverhalten eines Algorithmus zu betrachten, analysieren wir wieviele Operationen im schlechtesten Fall im bezug auf die größe des Problems (z.B.: Anzahl der Elemente) benötigt werden. Konstante Werte können dabei vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Suchen des kleinsten und größten Elements in einem Array.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 2 || 3 || 4 || 5 || 6&lt;br /&gt;
|}&lt;br /&gt;
Um das größte Element zu finden, werden 5 Schritte benötigt, dies entspricht der Länge des Arrays - 1. Für die Suche des größten Elements benötigen wir ebenfalls 5 Schritte. Somit ist die Laufzeit für unseren Algorithmus &#039;&#039;&#039;2 * (n - 1)&#039;&#039;&#039;, die Konstanten werden entfernt: &#039;&#039;&#039;O(n)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void findMinAndMax(int[] arr) {&lt;br /&gt;
  int min = arr[0];&lt;br /&gt;
  int max = arr[0];&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    min = Math.min(min, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    max = Math.max(max, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  System.out.println(&amp;quot;Min: &amp;quot;+min);&lt;br /&gt;
  System.out.println(&amp;quot;Max: &amp;quot;+max);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
== Bäume ==&lt;br /&gt;
Bäume sind Datenstrukturen, welche im Kontext von Suchstrukturen, automatisch einer gewissen Ordnung folgen. Bereits nach dem Einfügen sind diese Element sortiert.&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
Sortierte Ausgabe eines binären Suchbaums (In-Order)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void print(NOde node) {&lt;br /&gt;
  if(node == null) {&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  //Rekursiver aufruf für den Linken Teilbaum&lt;br /&gt;
  print(node.getLeft());&lt;br /&gt;
  System.out.print(&amp;quot; &amp;quot;+node.getValue()+&amp;quot; &amp;quot;);&lt;br /&gt;
  print(node.getRight());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=78</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=78"/>
		<updated>2021-01-06T08:58:20Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln. Um das Grenzverhalten eines Algorithmus zu betrachten, analysieren wir wieviele Operationen im schlechtesten Fall im bezug auf die größe des Problems (z.B.: Anzahl der Elemente) benötigt werden. Konstante Werte können dabei vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Suchen des kleinsten und größten Elements in einem Array.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 2 || 3 || 4 || 5 || 6&lt;br /&gt;
|}&lt;br /&gt;
Um das größte Element zu finden, werden 5 Schritte benötigt, dies entspricht der Länge des Arrays - 1. Für die Suche des größten Elements benötigen wir ebenfalls 5 Schritte. Somit ist die Laufzeit für unseren Algorithmus &#039;&#039;&#039;2 * (n - 1)&#039;&#039;&#039;, die Konstanten werden entfernt: &#039;&#039;&#039;O(n)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void findMinAndMax(int[] arr) {&lt;br /&gt;
  int min = arr[0];&lt;br /&gt;
  int max = arr[0];&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    min = Math.min(min, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    max = Math.max(max, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  System.out.println(&amp;quot;Min: &amp;quot;+min);&lt;br /&gt;
  System.out.println(&amp;quot;Max: &amp;quot;+max);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=77</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=77"/>
		<updated>2021-01-06T08:57:45Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln. Um das Grenzverhalten eines Algorithmus zu betrachten, analysieren wir wieviele Operationen im schlechtesten Fall im bezug auf die größe des Problems (z.B.: Anzahl der Elemente) benötigt werden. Konstante Werte können dabei vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Suchen des kleinsten und größten Elements in einem Array.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 2 || 3 || 4 || 5 || 6&lt;br /&gt;
|}&lt;br /&gt;
Um das größte Element zu finden, werden 5 Schritte benötigt, dies entspricht der Länge des Arrays - 1. Für die Suche des größten Elements benötigen wir ebenfalls 5 Schritte. Somit ist die Laufzeit für unseren Algorithmus &#039;&#039;&#039;2 * (n - 1)&#039;&#039;&#039;, die Konstanten werden entfernt: &#039;&#039;&#039;O(n)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public void findMinAndMax(int[] arr) {&lt;br /&gt;
  int min = arr[0];&lt;br /&gt;
  int max = arr[0];&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    min = Math.min(min, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  for(int i=1; i&amp;lt;arr.length; i++) {&lt;br /&gt;
    max = Math.max(max, arr[i]);&lt;br /&gt;
  }&lt;br /&gt;
  System.out.println(&amp;quot;Min: &amp;quot;+min);&lt;br /&gt;
  System.out.println(&amp;quot;Max: &amp;quot;+max);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=76</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=76"/>
		<updated>2021-01-06T08:52:25Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Landau Symbole oder O - Notation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln. Um das Grenzverhalten eines Algorithmus zu betrachten, analysieren wir wieviele Operationen im schlechtesten Fall im bezug auf die größe des Problems (z.B.: Anzahl der Elemente) benötigt werden. Konstante Werte können dabei vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Suchen des kleinsten und größten Elements in einem Array.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Text der Überschrift&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
|}&lt;br /&gt;
Um das größte Element zu finden, werden 5 Schritte benötigt, dies entspricht der Länge des Arrays - 1. Für die Suche des größten Elements benötigen wir ebenfalls 5 Schritte. Somit ist die Laufzeit für unseren Algorithmus &#039;&#039;&#039;2 * (n - 1)&#039;&#039;&#039;, die Konstanten werden entfernt: &#039;&#039;&#039;O(n)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=75</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=75"/>
		<updated>2021-01-06T08:42:12Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Vorteile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicherbedarf flexibel&#039;&#039;&#039; - Der Speicherbedarf wächst und schrumpft mit der Anzahl der Elemente.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
	<entry>
		<id>https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=74</id>
		<title>Algorithmen und Datenstrukturen</title>
		<link rel="alternate" type="text/html" href="https://ccwiki.digitalcampusvorarlberg.at/index.php?title=Algorithmen_und_Datenstrukturen&amp;diff=74"/>
		<updated>2021-01-06T08:41:29Z</updated>

		<summary type="html">&lt;p&gt;192.168.96.1: /* Nachteile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im folgenden Themenbereich geht es um Algorithmen und Datenstrukturen und um die Landau Symbole oder O - Notation und wie diese im Kontext von Algorithmen und Datenstrukturen verwendet wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Alghorithmen werden wir uns auf Sortieralgorithmen beschränken, uns mit deren Laufzeitanalyse (O - Notation) befassen&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Bei den Datenstrukturen beschränken wir uns auf Arrays, Listen und Bäume und ebenfalls um deren Laufzeitanalyse für verschiedene Operationen&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Landau Symbole oder O - Notation =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landau-Symbole&#039;&#039;&#039; (auch &#039;&#039;&#039;O-Notation&#039;&#039;&#039;) werden in der Mathematik und in der Informatik verwendet, um das asymptotische Verhalten von Funktionen und Folgen zu beschreiben. In der Informatik werden sie bei der Analyse von Algorithmen verwendet und geben ein Maß für die Anzahl der Elementarschritte oder der Speichereinheiten in Abhängigkeit von der Größe des gegebenen Problems an. (siehe [[https://de.wikipedia.org/wiki/Landau-Symbole]]).&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Unter asymptotischem Verhalten verstehen wir hier das Grenzverhalten eines Algorithmus, vereinfacht gesagt, wie kann sich die Laufzeit im schlechtesten Fall entwickeln.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In der O - Notation werden einige gebräuchliche Schranken verwendet, wenn wir einen Algorithmus oder eine Datenstruktur analysieren, verwenden wir diese Schranken und nicht die exakte Mathematische repräsentation des Problems (siehe [[Algorithmen_und_Datenstrukturen#Bubblesort|Bubblesort]])&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Gebräuchliche Beschränkungen (es gibt viele weitere!)&lt;br /&gt;
|-&lt;br /&gt;
! O - Notation !! Bedeutung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| O(1) || Das Laufzeitverhalten hängt nicht von der Anzahl der Elemente ab und ist konstant || Element an der Stelle N aus einem Array oder einer ArrayListe holen&lt;br /&gt;
|-&lt;br /&gt;
| O(n) || Das Laufzeitverhalten verlängert sich linear mit der Anzahl der Element || Suchen eines bestimmten Elements in einem unsortierten Array &lt;br /&gt;
|-&lt;br /&gt;
| O(n log n) || Super lineares Wachstum :-DDD || Mergesort, Heapsort, durchschnittsfall Quicksort&lt;br /&gt;
|-&lt;br /&gt;
| O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) || Quadratisches Wachstum, die Laufzeit wächst quadratisch zur Anzahl der Elemente || Bubblesort&lt;br /&gt;
|-&lt;br /&gt;
| O(log&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;n) || 2er Logarithmisches Wachstum || Suche im Binärbaum&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Datenstrukturen =&lt;br /&gt;
&lt;br /&gt;
In der Informatik und Softwaretechnik ist eine Datenstruktur ein Objekt, welches zur Speicherung und Organisation von Daten dient. Es handelt sich um eine Struktur, weil die Daten in einer bestimmten Art und Weise angeordnet und verknüpft werden, um den Zugriff auf sie und ihre Verwaltung effizient zu ermöglichen. (siehe [[https://de.wikipedia.org/wiki/Datenstruktur]])&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Im folgenden sollen einige Datenstrukturen erläutert werden, für jede Datenstruktur gibt es andere Einsatzgebiete die für deren Eigenschaften optimal sind.&lt;br /&gt;
&lt;br /&gt;
== Array ==&lt;br /&gt;
Ein Array oder Feld ist eine sehr effiziente doch wenig dynamische Datenstruktur. In nahezu allen Programmiersprachen findet sich diese Datenstruktur wieder. Weiter ist auch ein dynamisches vergrößern oder verkleinern in einigen Programmiersprachen automatisch implementiert (&#039;&#039;&#039;Javascript&#039;&#039;&#039;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Gehen wir jedoch von Programmiersprachen wie &#039;&#039;&#039;Java&#039;&#039;&#039; oder &#039;&#039;&#039;C&#039;&#039;&#039; aus, so hat ein Array immer eine fixe größe. Das heißt, zur Laufzeit (nach dem das Programm compiliert und gestartet wurde) kann diese nicht verändert werden.&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* &#039;&#039;&#039;Der Speicheroverhead ist sehr gering&#039;&#039;&#039; - Es wird nur der Speicher reserviert, der für die Anzahl der Elemente benötigt wird.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* &#039;&#039;&#039;Wenig flexibel&#039;&#039;&#039; - Wie bereits erwähnt, muss die größe meist fix definiert werden. Eine vergrößerung/verkleinerung ist nicht möglich, ermöglicht die Programmiersprache dies, so hat dies meist zurfolge, dass das Array neu erstellt wird, und die Elemente kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Überall dort, wo eine fixe Speichergröße benötigt und effizient wichtig ist, dort sollte die Verwendung von Arrays in betracht gezogen werden.&lt;br /&gt;
* &#039;&#039;&#039;Bildmanipulation&#039;&#039;&#039; - Wird ein Bild zur Bearbeitung geladen, so kann die &#039;&#039;Bitmap&#039;&#039; in einem Array gespeichert werden. jedes Element im Array entspricht dann einem Pixel.&lt;br /&gt;
* &#039;&#039;&#039;Puffern von Daten&#039;&#039;&#039; - Beim Lesen und Schreiben werden Daten meist in einem Array zwischengespeichert (gepuffert). Danach kann die Bearbeitung erfolgen. Weiters kann bei jedem Lese oder Schreibvorgang erneut das selbe Array verwendet werden, was die Effizienz weiter erhöht.&lt;br /&gt;
* &#039;&#039;&#039;Jegliches Schachbrettartige Problem mit fixer Größe&#039;&#039;&#039; - Schiffe versenken, Schach,...&lt;br /&gt;
&lt;br /&gt;
== Liste ==&lt;br /&gt;
Die Liste ist eine sehr gebräuchliche Datenstruktur. Sie ist gekennzeichnet durch, je nach implementierung, gute Zugriffszeiten oder erhöhte Flexibilität.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Beziehen wir uns auf die Programmiersprache Java, so ist die Liste ein &#039;&#039;&#039;Interface&#039;&#039;&#039;, das heißt eine Schnittstelle. Diese Schnittstelle definiert einige &#039;&#039;&#039;Methoden&#039;&#039;&#039; die eine Implementierung erfüllen muss. Einige davon wären:&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E get(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;E remove(int index)&amp;lt;/syntaxhighlight&amp;gt; - Gibt das Element an der Stelle &#039;&#039;&#039;index&#039;&#039;&#039; aus&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an das Ende der Liste an&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;boolean add(int index, E element)&amp;lt;/syntaxhighlight&amp;gt; - Fügt ein Element an einer bestimmten Position ein, und schiebt nachfolgende Elemente nach rechts (Index wird erhöht)&lt;br /&gt;
* ...&lt;br /&gt;
Hier ist nun ersichtlich, dass die Flexibilität der Liste ein essenzieller Bestandteil der Definition ist.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Anbei einige Implementierungen des Interfaces List.&lt;br /&gt;
=== ArrayList ===&lt;br /&gt;
Die ArrayList vereint die Eigenschaften einer Liste und eines Arrays. Die interne Implementierung verwendet ein Array von fixer größe um Elemente zu speichern. Wird diese fixe größe überschritten, so wird  intern ein neues Array angelegt, je nach implementierung mit einem gewissen Vergrößerungsfaktor. Nach dem neuanlegen des internen Arrays, werden alle Elemente kopiert und in das neue Array eingefügt. Werden Elemente gelöscht, so müssen die Elemente nach dem gelöschten Element um eins nach links verschoben werden.&lt;br /&gt;
[[Datei:Removing Element from ArrayList diagram.png|mini|none|400px|Element wird aus ArrayListe entfernt. Quelle: https://beginnersbook.com/2013/12/java-arraylist/]]&lt;br /&gt;
In Java wird die größe des internen Arrays nicht automatisch reduziert, wenn Elemente gelöscht werden. Dafür gibt es die Methode &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; inline&amp;gt;myArrayList.trim()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Relativ geringer Speicheroverhead&#039;&#039;&#039; - Dies verhält sich ähnlich wie beim Array. Jedoch können in der ArrayList keine primitiven Datentypen gespeichert werden. Dies bedeutet, es wird nur ein Array von Referenzen erstellt. In jedem Platz findet sich eine Referenz auf das wirkliche Objekt. Dies bedeutet in Bezug auf primitive Datentypen einen weit höheren Speicherbedarf als bei einem Array.&lt;br /&gt;
* &#039;&#039;&#039;Geringe Zugriffszeit&#039;&#039;&#039; - Wird ein Element an einer stelle angesprochen, so kann für den Zugriff die Exakte Speicheradresse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Löschen&#039;&#039;&#039; - Laufzeit beim Löschen nicht optimal, Elemente müssen verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Einfügen&#039;&#039;&#039; - Laufzeit beim Einfügen von Elementen an einer gewissen Stelle langsam, wie beim löschen müssen alle Nachfolgenden Elemente verschoben werden.&lt;br /&gt;
* &#039;&#039;&#039;Ineffizientes Hinzufügen, wenn internes Array voll&#039;&#039;&#039; - Laufzeit beim Hinzufügen von Elementen bei vollem Array langsam, ein neues Array muss erstellt werden und alle Elemente&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;gt;&lt;br /&gt;
List&amp;lt;Integer&amp;gt; myArrayList = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.add(1);&lt;br /&gt;
myArrayList.remove(0);&lt;br /&gt;
System.out.println(&amp;quot;Element an der Stelle 2: &amp;quot;+myArrayList.get(1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zeile 1) Die die ArrayListe wird erzeugt und einer Variable des Typs List zugewiesen. Warum ist das möglich? Weil ArrayList das Interface List implementiert. D.h.: Eine ArrayList ist eine List.&lt;br /&gt;
* Zeile 2) - 4) fügen dem Array einen int hinzu. Hier ist zu beachten, der primitive Datentyp &#039;&#039;&#039;int&#039;&#039;&#039; wird automatisch in die Klasse &#039;&#039;&#039;Integer&#039;&#039;&#039; umgewandelt. Dieser mechanismus nennt sich Autoboxing.&lt;br /&gt;
* Zeile 5) Das Element an der Stelle 0 wird aus der ArrayList entfernt&lt;br /&gt;
* Zeile 6) Ausgabe des Elements an der Stelle 2 (Index 1)&lt;br /&gt;
&lt;br /&gt;
=== Einsatzgebiete ===&lt;br /&gt;
Die Einsatzgebiete überschneiden sich mit herkömmlichen Arrays. Benötigt man mehr flexibilität und soll &#039;&#039;&#039;nicht&#039;&#039;&#039; mit primitiven Datentypen gearbeitet werden, so kann anstatt eines Arrays die ArrayListe verwendet werden. Ist die Anzahl der Elemente start fluktuierend (oftmaliges löschen/einfügen/hinzufügen), so sollte man aus oben genannten Gründen auf eine andere Datenstruktur ausweichen.&lt;br /&gt;
&lt;br /&gt;
=== LinkedList oder verkettete Liste ===&lt;br /&gt;
Die verkettete Liste ist eine sehr dynamische Datenstruktur. Ihre Größe ist flexibel. Die Daten werden in Knoten gehalten, welche im Falle der einfach verketteten Liste auf den Nachfolger und bei der doppelt verketteten Liste zusätzlich auf den Vorgänger Knoten zeigen. Elemente können einfach an bestimmten Stellen eingefügt oder gelöscht werden, es müssen lediglich die Nachfolger bzw. Vorgänger aktualisiert werden.&lt;br /&gt;
[[Datei:Singly linked list and doubly linked list in Java.jpg|mini|none|Einfach und doppelt verkettete Liste. Quelle: https://www.java67.com/2016/01/how-to-implement-singly-linked-list-in-java-using-generics-example.html]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* &#039;&#039;&#039;Einfügen und Löschen effizient&#039;&#039;&#039; - Es müssen lediglich die Zeiger auf den Vorgänger/Nachfolger geändert werden.&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* &#039;&#039;&#039;Zufälliger Zugriff langsam&#039;&#039;&#039; - Werden in der LinkedList Elemente mit ihrem Index angesprochen, so muss zuerst die komplette Liste bis zum entsprechenden Index durchlaufen werden.&lt;br /&gt;
* &#039;&#039;&#039;Speicheroverhead&#039;&#039;&#039; - Da die Daten in Knoten gespeichert werden müssen entsteht automatisch ein Speicheroverhead.&lt;br /&gt;
&lt;br /&gt;
==== Einsatzgebiete ====&lt;br /&gt;
* Wenn die größe der Liste stark variiert, d.h. oftmals Elemente eingefügt, gelöscht und hinzugefügt werden und &#039;&#039;&#039;kein&#039;&#039;&#039; zufälliger Zugriff benötigt wird.&lt;br /&gt;
&lt;br /&gt;
==== Code beispiel ====&lt;br /&gt;
&#039;&#039;Hinzufügen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public boolean add(Integer element) {&lt;br /&gt;
  Node newNode = new Node(element);&lt;br /&gt;
  if(root == null) {&lt;br /&gt;
    root = newNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Node current = root;&lt;br /&gt;
    while(current.next() != null) {&lt;br /&gt;
      current = current.next();&lt;br /&gt;
    }&lt;br /&gt;
    current.setNext(newNode);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Holen eines Elements&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public Integer get(int index) {&lt;br /&gt;
  Node current = root;&lt;br /&gt;
  for(int i=0; i&amp;lt;index &amp;amp;&amp;amp; current != null; i++) {&lt;br /&gt;
    current = current.next();&lt;br /&gt;
  }&lt;br /&gt;
  if(current == null) {&lt;br /&gt;
    throw new IndexOutOfBoundsException();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assoziatives Array ==&lt;br /&gt;
Das &#039;&#039;&#039;assoziative Array&#039;&#039;&#039; oder auch Map, ist eine Sammlung von &#039;&#039;&#039;Key&#039;&#039;&#039;, &#039;&#039;&#039;Value&#039;&#039;&#039; Paaren. Sie eignet sich sehr gut dafür, für einen bestimmten Schlüssel einen Wert zu hinterlegen. Die Operationen, einfügen, löschen, abrufen, sind Konstant und weisen im Normalfall ein Laufzeitverhalten von O(1) auf. Die Reihenfolge der Element ist nicht definiert.&lt;br /&gt;
&lt;br /&gt;
= Sortieralgorithmen =&lt;br /&gt;
Sortieralgorithmen werden benötigt um Datenstrukturen nach gewissen Kriterien zu sortieren. Dazu müssen die Elemente natürlich vergleichbar sein, d.h. es muss möglich sein herauszufinden ob ein Element &amp;quot;größer&amp;quot; oder &amp;quot;kleiner&amp;quot; als ein anderes ist.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften == &lt;br /&gt;
Sortieralgorithmen können über mehrere Eigenschaften verfügen.&lt;br /&gt;
=== In-Place ===&lt;br /&gt;
Das bedeutet der Sortieralgorithmus benötigt &amp;quot;keinen&amp;quot; weiteren Speicherplatz beim sortieren, bzw. wenn der Speicherbedarf konstant ist, und nicht mit der Anzahl der Elemente wächst. Z.b. der Sortieralgorithmus Mergesort, teilt die Daten der bestehenden Liste in Sublisten auf, er ist somit nicht In-Place.&lt;br /&gt;
=== Stabil ===&lt;br /&gt;
Ein Sortieralgorithmus arbeitet stabil, wenn dieser eine bestehende korrekte Ordnung nicht verändert.&lt;br /&gt;
&lt;br /&gt;
== Bubblesort ==&lt;br /&gt;
Bubblesort ist ein vergleichsweise akademischer Algorithmus. Er ist wenig effizient, arbeitet jedoch &#039;&#039;&#039;Stabil&#039;&#039;&#039; und &#039;&#039;&#039;In-Place&#039;&#039;&#039;.&lt;br /&gt;
[[Datei:Bubble-sort-example-300px.gif|mini|none|Funktionsweise Bubblesort. Quelle: https://de.wikipedia.org/wiki/Bubblesort]]&lt;br /&gt;
&lt;br /&gt;
=== Code ===&lt;br /&gt;
Bubblesort in Java&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;Java&#039; line=&amp;quot;&#039;line&#039;&amp;quot;&amp;gt;&lt;br /&gt;
public class Bubblesort {&lt;br /&gt;
	public static void sort(int[] arr) {&lt;br /&gt;
		int operations = 0;&lt;br /&gt;
		int n = arr.length;&lt;br /&gt;
		boolean swapped = false;&lt;br /&gt;
		do {&lt;br /&gt;
			swapped = false;&lt;br /&gt;
			for (int i = 0; i &amp;lt; n - 1; i++) {&lt;br /&gt;
				operations++;&lt;br /&gt;
				if (arr[i] &amp;gt; arr[i + 1]) {&lt;br /&gt;
					int tmp = arr[i];&lt;br /&gt;
					arr[i] = arr[i + 1];&lt;br /&gt;
					arr[i + 1] = tmp;&lt;br /&gt;
					swapped = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// Letztes Element ist an der richtigen stelle, n um 1 reduzieren&lt;br /&gt;
			n = n - 1;&lt;br /&gt;
		} while (swapped);&lt;br /&gt;
		System.out.println(&amp;quot;Operations: &amp;quot; + operations);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
		arr = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };&lt;br /&gt;
		sort(arr);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Laufzeitanalyse ===&lt;br /&gt;
Für die Laufzeitanalyse verwenden wir die maximal mögliche Laufzeit.&lt;br /&gt;
Betrachten wir hierfür folgendes Array:&lt;br /&gt;
10,8,5,3,2,1&lt;br /&gt;
* 1) Durchlauf: Die Zahl 10 wird mit 8,5,3,2 und 1 verglichen und vertauscht. &lt;br /&gt;
* 2) Durchlauf: Die Zahl 8 wird mit 5,3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 3) Durchlauf: Die Zahl 5 wird mit 3,2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 4) Durchlauf: Die Zahl 3 wird mit 2 und 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* 5) Durchlauf: Die Zahl 2 wird mit 1 verglichen und vertauscht, &#039;&#039;&#039;mit 10, 8, 5, 3 muss nichtmehr verglichen werden&#039;&#039;&#039;.&lt;br /&gt;
* Ende, die Zahl 1 muss nichtmehr verglichen werden.&lt;br /&gt;
&lt;br /&gt;
Vergleichen und vertauschen betrachten wir nun als eine Operation.&lt;br /&gt;
&lt;br /&gt;
* 1) Durchlauf -&amp;gt; 5 Operationen&lt;br /&gt;
* 2) Durchlauf -&amp;gt; 4 Operationen&lt;br /&gt;
* 3) Durchlauf -&amp;gt; 3 Operationen&lt;br /&gt;
* 4) Durchlauf -&amp;gt; 2 Operationen&lt;br /&gt;
* 5) Durchlauf -&amp;gt; 1 Operation&lt;br /&gt;
&lt;br /&gt;
Das sind für ein Array der Länge 6, 15 Operationen.&lt;br /&gt;
&lt;br /&gt;
==== Die allgemeine Formel lautet ====&lt;br /&gt;
* 1) (n-1) + (n-2) + ... 1&lt;br /&gt;
* 2) &#039;&#039;Das ist ja der kleine Gauß minus n:&#039;&#039; (n * (n + 1))/2 - n&lt;br /&gt;
* 3) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + n - 2*n)/2&lt;br /&gt;
* 4) (n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)/2&lt;br /&gt;
* 5) 1/2*(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n)&lt;br /&gt;
* 6) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - n -&amp;gt; Konstante Werte werden bei der O - Notation entfernt&lt;br /&gt;
* 7) n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; -&amp;gt; n ist zu n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; vernachlässigbar und wird entfernt&lt;br /&gt;
&lt;br /&gt;
==== Laufzeit ====&lt;br /&gt;
&#039;&#039;&#039;Somit ist die Laufzeit von Bubblesort O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)&#039;&#039;&#039;&lt;br /&gt;
==== Laufzeit Bestcase ====&lt;br /&gt;
Liegt bereits eine sortierte Liste vor, so benötigt Bubblesort nur einen Durchlauf. Dabei erfolgen &#039;&#039;&#039;n - 1&#039;&#039;&#039; vergleiche. Die Konstante wird entfernt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Die Laufzeit im Bestcase ist O(n)&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>192.168.96.1</name></author>
	</entry>
</feed>