Skip to content

Commit 2fcce00

Browse files
authored
fix: headline hierarchy (#37)
* fix: headline hierarchy * fix: camunda redirect
1 parent 3e33dc4 commit 2fcce00

11 files changed

+33
-30
lines changed

astro.config.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import tailwind from '@astrojs/tailwind'
55
import rehypeExternalLinks from 'rehype-external-links'
66
import mdx from '@astrojs/mdx'
77

8-
import sitemap from '@astrojs/sitemap';
8+
import sitemap from '@astrojs/sitemap'
99

1010
// https://astro.build/config
1111
export default defineConfig({
@@ -26,4 +26,7 @@ export default defineConfig({
2626
],
2727
],
2828
},
29-
})
29+
redirects: {
30+
'/leistungen/camunda': '/leistungen/camunda-automatisierung',
31+
},
32+
})

src/content/blog/camunda-string-variablen.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,5 @@ public ObjectValue getMailBody() {
7676
}
7777
```
7878

79-
### Zusammenfassung
79+
## Zusammenfassung
8080
Prozess-Variablen in Camunda als Objekte zu implementieren hat mehrere Vorteile: Durch die dazugehörige Java-Klasse entsteht eine Typsicherheit, es gibt keine Größenbegrenzung durch die Camunda Datenbank und es trägt zur Übersichtlichkeit bei. An manchen Stellen, wie bei den lokalen Variablen, ist der Aufwand allerdings höher, da Probleme, welche theoretisch ausschließlich im BPMN-Diagramm gelöst werden könnten, in eine Java-Klasse ausgelagert werden müssen. Nichtsdestotrotz lohnt sich der Mehraufwand und man sollte primitive Typen in den Prozess-Variablen nur benutzen, wenn man sich sehr sicher über den Inhalt der Variable sein kann.

src/content/blog/ecmascript-mengenoperationen.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Bei einem unserer Projekte sind wir kürzlich auf ein unerwartete Performance-Pr
1717

1818
JavaScript bzw. ECMAScript (der "richtige" Name der Sprache) brachte lange Zeit keine expliziten Funktionen für Mengenoperationen mit. Obwohl diese Funktionen schon lange diskutiert wurden, erreichten sie [erst 2024 die "Stage 4"](https://github.com/tc39/ecma262/pull/3306), wurden also offiziell in den Standard aufgenommen. Seit einigen Monaten gibt es nun also in den meisten Runtimes explizit die Möglichkeit, Mengenoperationen wie `.union()`, `.intersection()` und `.difference()` an `Set`-Objekten berechnen zu lassen. Im Internet findet man aber natürlich oftmals noch Code, welcher für diese Aufgabe kein `Set` verwendet. Wir haben also alte und neue Optionen miteinander verglichen:
1919

20-
### Vorbereitung: Wir bauen uns zwei große Arrays
20+
## Vorbereitung: Wir bauen uns zwei große Arrays
2121
Für die folgenden Vergleiche haben wir jeweils die gleichen zwei Arrays mit einer beispielhaften Länge von 200.000 Elementen initialisiert. Der Inhalt dieser Objekte spielt hier keine besondere Rolle. Nur so viel: Sie enthalten jeweils eine ID, über die sie eindeutig identifiziert werden können. Wir suchen also in beiden Arrays diejenigen Objekte mit der gleichen ID.
2222

2323
```ts
@@ -32,7 +32,7 @@ const bigArray2 = Array.from(
3232

3333
```
3434

35-
### Vergleichen mit Schleifen oder `.filter()` und `.some()`
35+
## Vergleichen mit Schleifen oder `.filter()` und `.some()`
3636

3737

3838
```ts
@@ -59,7 +59,7 @@ outerLoop: for (const array1Element of bigArray1) {
5959

6060
Dieser Code war unser erster, naiver Ansatz zum Bilden der Differenz: Die Verwendung von `.filter()` ist ein klassisches Konzept aus der funktionalen Programmierung. Der Code ist kurz und gut verständlich und es wird dabei relativ wenig Speicher verbraucht. Der Nachteil dieser Variante ist aber, dass relativ viel Zeit benötigt wird. Der Aufwand für die Laufzeit dieses Algorithmus wird als `O(n²)` beschrieben – das heißt, jedes Array-Element des ersten Arrays wird mit jedem Array-Element des zweiten Arrays verglichen (also in diesem Fall finden `200.000² = 40 Mrd.` Vergleichsoperationen statt). Auch die zweite Code-Variante basiert genau auf diesem Grundsatz, benutzt jedoch zwei for-Schleifen statt dem funktionalen `filter()`-Aufruf und braucht deswegen etwa genau so lange für die Berechnung. Beide Varianten sind also nur dann sinnvoll, wenn wenig Arbeitsspeicher zur Verfügung steht oder die beiden Arrays eine Größe haben, bei denen die Laufzeit egal ist.
6161

62-
### Ein Array von IDs und Array.includes()
62+
## Ein Array von IDs und Array.includes()
6363
```ts
6464
// Option 2
6565
const bigArray2Ids = bigArray2.map((obj) => obj.id);
@@ -72,7 +72,7 @@ const diff = bigArray1.filter(
7272

7373
Bei der zweiten Option haben wir `Array.includes()` benutzt, um zu prüfen, ob eine Logzeile in dem Array vorhanden ist. Da `includes()` die Referenzen der Objekte vergleicht, und nicht deren Inhalt, müssen wir hier die IDs statt der kompletten Objekte benutzen. Deswegen erstellen wir zuerst ein Array mit allen IDs von einem der beiden Logfiles und sortieren dann diejenigen Einträge aus dem zweiten Logfile, deren IDs bereits im ersten Array enthalten sind. Die Laufzeit verbessert sich in diesem Ansatz etwas, dafür ist nun der Speicherbedarf höher, da wir ein zusätzliches Array mit den IDs benötigen. Diese Variante ist vielleicht etwas weniger intuitiv als die erste Variante und der Laufzeit-Vorteil ist relativ gering.
7474

75-
### Sets mit JSON.stringify()
75+
## Sets mit JSON.stringify()
7676
```ts
7777
// Option 3
7878
const bigArray2StringifiedSet = new Set(
@@ -95,7 +95,7 @@ const diff = differenceStringified.map((obj) =>
9595

9696
Nun verwenden wir endlich die "neuen" Mengenoperationen (konkret die `.difference()`-Operation). Diese arbeiten aber nur mit Sets: das heißt wir müssen beide Arrays zunächst in geeignete Sets überführen. Da aber auch hier Referenzen von den jeweiligen Objekten verglichen werden würden, benutzen wir nun `JSON.stringify()`, um vergleichbare Strings aus den Objekten zu erzeugen. Der Haken hier dran ist, dass beide Objekte die gleichen Eigenschaften haben müssen – die gleiche ID reicht nicht aus. Alternativ könnte man die Mengenoperation auch nur auf die zwei Sets der IDs anwenden. Dann müsste man im Nachhinein aber wieder die verbleibenden IDs zu ihren ursprünglichen Objekten auflösen – was in Summe langsamer ist, als dieser `JSON.stringify()`-Ansatz. Hier stellen wir nun das erste mal einen deutlichen Sprung in der Laufzeit fest. Die Komplexität des Algorithmus sinkt nämlich wahrscheinlich auf `O(n)` (abhängig von der Implementierung in der jeweiligen JavaScript-Engine). Der Speicherbedarf ist allerdings auch deutlich gestiegen, da wir beide Arrays nicht nur duplizieren, sondern auch als serialisierte Strings im Speicher halten.
9797

98-
### Am schnellsten: Objektfelder als Lookup-Table
98+
## Am schnellsten: Objektfelder als Lookup-Table
9999
```ts
100100
// Option 4
101101
const map = {};
@@ -113,5 +113,5 @@ Die mit Abstand schnellste Variante ist es, ein Objekt als eine einfache "Lookup
113113

114114

115115

116-
### Fazit: Überall Footguns, auch bei Mengenoperationen
116+
## Fazit: Überall Footguns, auch bei Mengenoperationen
117117
Wie so oft in der Informatik gilt auch hier: Vorteile in der Laufzeit bedeuten leider fast immer Nachteile im Speicherbedarf. JavaScript macht es mit seinen neuen Mengenoperationen sehr einfach, solche Operationen auszuführen. Oftmals ist diese "naive" Herangehensweise allerdings nicht sehr performant – es handelt sich also um eine sogenannte "Footgun" (etwas vermeintlich Einfaches, bei dem sich der Entwickler sprichwörtlich in den Fuß schießen kann). Bei großen Datenmengen lohnt sich definitiv der Blick auf andere Algorithmen, da die Zeiteinsparungen ein Vielfaches (in unserem Beispielfall: Faktor 170) betragen können.

src/content/blog/nextcloud-freigabe-chaos.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Die Verbreitung und Popularität von Open-Source-Software hat im Jahr 2023 noch
1818

1919
Die Motivation und Euphorie beim Start einer neuen Nextcloud-Instanz sind oft sehr groß. Endlich eigene, unabhängige Infrastruktur zu nutzen, fühlt sich zunächst toll an. Über die Web-Oberfläche oder die verschiedenen Client-Anwendungen füllt sich die Nextcloud schnell mit den ersten Dateien. Und irgendwann kommt der Moment, wo mindestens zwei Benutzer oder vielleicht sogar eine ganze Gruppe von Benutzern eine Datei oder einen Ordner miteinander teilen möchten. Klingt eigentlich simpel, denn dieses Szenario beschreibt ja schließlich die Gründungsidee von Nextcloud (bzw. OwnCloud). Doch diese Aufgabe (Teilen von Dateien in einer festen Gruppe von Personen) ist gar nicht so trivial zu bewerkstelligen. Nextcloud bietet inzwischen mindestens drei verschiedene Mechanismen dafür an.
2020

21-
### Shares: Der naheliegendste Weg mit vielen Fallstricken
21+
## Shares: Der naheliegendste Weg mit vielen Fallstricken
2222

2323
Die einfachste Lösung für dieses Problem ist also auch die Älteste: die eingebaute "Teilen"-Funktion von Nextcloud. Neben jeder Datei und jedem Ordner in Nextcloud gibt es ein kleines "Share"-Icon, welches einen Dialog öffnet, in dem sich eine Datei oder ein Ordner mit anderen Nextcloud-Nutzern oder Gruppen teilen lässt. Das ist einfach und leicht verständlich – und gefährlich. Diese Funktion sorgt gerade in Organisationen mit vielen Benutzern oft für viel Chaos: Technisch gesehen verhält sich eine solche Nextcloud-Freigabe eigentlich wie ein sogenannter [symbolischer Link](https://de.m.wikipedia.org/wiki/Symbolische_Verkn%C3%BCpfung) in einem Dateisystem. Deswegen gibt es einige weniger bekannte Nebeneffekte:
2424

@@ -28,7 +28,7 @@ Die einfachste Lösung für dieses Problem ist also auch die Älteste: die einge
2828

2929
Für sehr kleine und private Instanzen ist die einfache Share-Funktion meistens noch ausreichend. Mit steigender Anzahl von Nutzern und festen Teams wird die Funktion allerdings sehr schnell unübersichtlich. Im professionellen Umfeld ist die Funktion kaum zu beherrschen und birgt die Gefahr, dass Mitarbeiter ihre Dokumente nicht mehr finden, wenn Nutzer ausscheiden. Wer eine Übersicht über die Menge an eingerichteten Shares haben möchte, kann dazu das [`sharelisting`-Plugin](https://github.com/nextcloud/sharelisting) nutzen.
3030

31-
### Gruppenordner: Fast perfekt aber wenig gepflegt
31+
## Gruppenordner: Fast perfekt aber wenig gepflegt
3232

3333
Um viele der genannten Probleme bei der Arbeit mit Gruppen zu beseitigen, gibt es bereits [seit 2017](https://nextcloud.com/blog/new-version-of-groupfolders-app-is-coming/) das offizielle ["groupfolders"-Plugin](https://github.com/nextcloud/groupfolders) für Nextcloud. Kurioserweise gehören Gruppen zwar zum Standard-Funktionsumfang von Nextcloud, aber nicht das Plugin für Gruppenordner. Die zugrundeliegenden Gruppen können nur von Admins in Nextcloud verwaltet werden. Gruppenbasierte Funktionalitäten eignen sich also tendenziell gut für hierarchisch strukturierte Organisationen und Firmen, wo klar definiert ist, wer über eine Gruppenzuordnung entscheiden kann.
3434

@@ -44,7 +44,7 @@ Um viele der genannten Probleme bei der Arbeit mit Gruppen zu beseitigen, gibt e
4444

4545
Für die Zusammenarbeit in einer festen und hierarchischen Gruppen-Konstellation (wie sie üblicherweise im Arbeitsumfeld vorkommt) scheinen Groupfolders also eine überlegene Lösung zu sein. Trotzdem fühlt sich das groupfolders-Plugin manchmal wie ungewollter Ballast im Nextcloud-Universum an. Obwohl das Plugin offiziell von der Nextcloud GmbH verwaltet wird, bekommt es augenscheinlich nur [wenig Priorität und Ressourcen](https://github.com/nextcloud/groupfolders/issues/1215) zugewiesen und weist deswegen teilweise monatelang gravierende Fehler auf.
4646

47-
### Teams: Aufgebohrte Share-Funktion
47+
## Teams: Aufgebohrte Share-Funktion
4848

4949
["Teams"](https://github.com/nextcloud/circles)(früher "Circles") ist eine dritte Variante um mit einer Gruppe Dateien und Ordner zu teilen. Teams wirken aber eher wie eine kleine Erweiterung der einfachen Share-Funktionalität. Anstelle einzelner Nutzer und (durch Admins definierte) Gruppen, können Dateien und Ordner damit auch mit selbstverwalteten Teams geteilt werden. Teams können von jedem Nutzer erstellt werden (vorausgesetzt die zugehörige Nextcloud-App ist installiert), und benötigen keinerlei Admin-Intervention. Teams ermöglichen also Selbstorganisation in Strukturen, wo keine klare Hierarchie oder Zuständigkeit herrscht. Die so erstellten Freigaben leiden allerdings unter denselben Problemen wie die einfachen Dateifreigaben:
5050

src/content/blog/webapps.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,28 @@ Webanwendungen sind in den letzten Jahren (spätestens seit dem "Web 2.0") immer
1717

1818
Webanwendungen (auf Englisch auch Web-Apps genannt) sind Softwareanwendungen, die über einen Webbrowser aufgerufen und genutzt werden. Von einfachen Webseiten grenzen sich Webanwendungen durch eine höhere Komplexität ab. Bekannte Beispiele für Web-Apps sind zum Beispiel solche Anwendungen wie die Online-Office-Lösung [Google Docs](https://www.google.com/docs/about/), die Design-Programme [Figma](https://www.figma.com/) oder [Canva](https://www.canva.com/) oder das Videostreaming-Portal [Netflix](https://www.netflix.com). Im Gegensatz zu traditionellen Desktop- oder mobilen Anwendungen (auch "native" Anwendungen genannt) müssen sie meistens nicht auf dem Gerät installiert werden, sondern können einfach über eine Internetadresse (URL) aufgerufen und genutzt werden.
1919

20-
### 👁️ Zugänglichkeit: Ein Browser reicht aus
20+
## 👁️ Zugänglichkeit: Ein Browser reicht aus
2121

2222
Webanwendungen werden über einen Webbrowser aufgerufen. Das bedeutet, dass jedes Gerät, auf welchem ein moderner Browser installiert werden kann (egal ob es sich um einen PC, ein Smartphone, ein Tablet, ein Auto oder einen Fernseher handelt) diese ausführen kann, unabhängig vom Betriebssystem oder der darunterliegenden Hardware. Mit einer einzigen Applikation können also wahnsinnig viele Gerätearten und -kategorien abgedeckt werden. Dank dem sogenannten Responsive Design können Webanwendungen auch auf alle Bildschirmgrößen zugeschnitten werden. Das reduziert den Entwicklungsaufwand deutlich gegenüber nativen Anwendungen und verringert die Abhängigkeit von speziellen Herstellern oder Plattformen. Entwickelt man z.B. eine native iOS-App, so ist man auch in Zukunft an Apple-Hardware gebunden – dies ist bei Web-Apps nicht der Fall. Die Web-Technologie erlaubt es außerdem relativ gut, Software auch für Menschen mit Beeinträchtigung (etwa Seh- oder Motorikbeeinträchtigungen) zugänglich zu machen.
2323

24-
### 🕸️ Zentralisierung: Geteilte Daten, keine Backups und offene Schnittstellen
24+
## 🕸️ Zentralisierung: Geteilte Daten, keine Backups und offene Schnittstellen
2525

2626
Webapplikationen bestehen häufig aus einer Server-Komponente (Backend) und einer Benutzeroberfläche (Frontend). Das Frontend ist die eigentliche Web-App und wird im Browser des Benutzers ausgeführt. Das Backend läuft meistens auf einem (oder mehreren) zentralisierten Server(n). Das Frontend kann dabei idealerweise sehr schlank gestaltet werden, so dass der Nutzer nur die Daten vom Server bekommt, welche er tatsächlich benötigt. Die Geschäftslogik (z.B. Berechnungen etc.) als auch die Daten liegen auf dem Server und können von vielen Nutzern geteilt werden. Eine gemeinsame Datenbasis zwischen allen Nutzern erleichtert die Kollaboration und macht das Austauschen von Dateien oder das Nutzen von Netzlaufwerken häufig unnötig.
2727

2828
<figure class="[&>p>img]:mx-auto [&>p>img]:mb-0">![](/images/blog/webapps/webapps_figma.png)<figcaption>Ein Screenshot aus der beliebten Design-Anwendung Figma, die komplett im Browser verwendet werden kann.</figcaption></figure>
2929

3030
Durch die Zentralisierung der Daten müssen auch kaum Daten beim Nutzer gespeichert werden, wodurch dem Nutzer auch keine Daten verloren gehen können (Laptop geklaut, Wasserschaden, etc.). Am wichtigsten finden wir allerdings, dass es im Kontext von Web-Apps gängig und einfach ist, eine generische Programmier-Schnittstelle zur Verfügung zu stellen, die auch von anderen Programmen genutzt werden kann. Programme sollten heutzutage immer eine Möglichkeit bieten, im Zusammenspiel mit anderen Anwendungen zu funktionieren, sonst ist eine Automatisierung eines Prozesses, in welchem dieses Programm vorkommt, nicht möglich. Dadurch, dass bei einer Web-App meistens ein Server vorhanden ist, der eine Schnittstelle für das Frontend bereitstellt, kann diese Schnittstelle oft auch von anderen Programmen verwendet werden.
3131

32-
### 📲 Updates passieren automatisch
32+
## 📲 Updates passieren automatisch
3333

3434
Eine Software, die nicht gewartet wird, stirbt bekanntlich irgendwann aus. Updates sind essentiell, um Fehler zu beheben, neue Features einzubauen und die Software an neue Bedingungen anzupassen. Daher ist es von großem Vorteil, wenn jeder Benutzer immer die aktuelle Version einer Software benutzt. Bei nativen Anwendungen bedeutet das, dass auf jedem Gerät das Update installiert werden muss. Je nach Art der Nutzer, bedeutet das einen großen Administrationsaufwand (z.B. in einer Unternehmensstruktur) oder es dauert sehr lange, bis alle Nutzer das Update installiert haben, z.B. bei privaten Nutzern. Bei Webanwendungen dagegen laden die Nutzer die Anwendung meistens bei jedem Aufruf über das Netzwerk. Somit muss nur die Anwendung auf dem Server aktualisiert werden – die Clients updaten sich dann quasi von alleine. Der Administrationsaufwand wird dadurch drastisch reduziert.
3535

36-
### 💸 Web-Apps sind oft günstiger zu erstellen als native Anwendungen
36+
## 💸 Web-Apps sind oft günstiger zu erstellen als native Anwendungen
3737

3838
Alle oben beschriebenen Vorteile einer Webanwendung tragen erheblich dazu bei, die Kosten für den Betrieb und die Entwicklung einer Anwendung zu senken. Webanwendungen können nicht alles besser, aber sie sind oft ein sehr kosteneffizienter Weg, eine große Spanne an Funktionen abzudecken. Sowohl Frontend als auch Backend können zum Beispiel in einer gemeinsamen Programmiersprache (JavaScript/Typescript), geschrieben werden, wodurch eine schnelle und kosteneffiziente Entwicklung auch von einem kleinen Team möglich gemacht wird.
3939

4040

41-
### Nachteile: Immer online, wenig Hardware-Support und Tracking
41+
## Nachteile: Immer online, wenig Hardware-Support und Tracking
4242

4343
Natürlich sind Web-Apps kein Allheilmittel. Die vielen Vorteile bringen auch einige Nachteile mit sich, die nicht verschwiegen werden sollten:
4444

src/content/services/camunda-automatisierung.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import { LinkButton } from "@components";
1212

1313
In der heutigen Welt ist die Automatisierung von Prozessen ein entscheidender Faktor für den Erfolg eines Unternehmens. Digitale Prozesse versprechen oft höheren Durchsatz, bessere Effizienz und geringere Kosten als ihre analogen Gegenstücke. Mit [**Camunda**](https://camunda.com/), einer leistungsstarken und flexiblen Open-Source-Plattform, digitalisieren und automatisieren wir Ihre Geschäftsprozesse auf nachhaltige und sinnvolle Art.
1414

15-
### Was ist Camunda?
15+
## Was ist Camunda?
1616

1717
**Camunda** ist eine moderne Plattform zur Workflow- und Entscheidungsautomatisierung, die sich nahtlos in bestehende IT-Infrastrukturen integrieren lässt. Sie unterstützt sowohl **BPMN** (Business Process Model and Notation) als auch **DMN** (Decision Model and Notation) als Modellierungssprache, wodurch Unternehmen in der Lage sind, sowohl komplexe Workflows als auch Geschäftsentscheidungen zu modellieren und zu automatisieren.
1818

19-
### Vorteile der Prozessautomatisierung mit Camunda
19+
## Vorteile der Prozessautomatisierung mit Camunda
2020

2121
- **Effizienzsteigerung**: Durch die Automatisierung manueller Prozesse werden Arbeitsabläufe beschleunigt und Fehler reduziert.
2222
- **Skalierbarkeit**: Camunda bietet die Möglichkeit, Prozesse auf Unternehmensebene zu skalieren und zu optimieren.

0 commit comments

Comments
 (0)