Auftrennung in zwei getrennte Bewerbungen als Admin oder Senior Dev
This commit is contained in:
1 parent
de9ab4edc7
commit
3f1013faa4
9 files changed
+426
-51
No files matched your search
+2
-1
@@ -1,2 +1,3 @@
|
||||
.DS_Store
|
||||
07_bewerbung-typst/build
|
||||
07_bewerbung-typst/Admin/*.pdf
|
||||
07_bewerbung-typst/Senior Developer/*.pdf
|
||||
@@ -2,4 +2,5 @@
|
||||
|
||||
- Vor dem Lesen, Bearbeiten oder Kompilieren der Dokumente zuerst das `Makefile` lesen. Die aktuellen Quelldateien stehen in `COVERLETTER_SRC` und `CV_SRC`; die PDF-Pfade werden dort abgeleitet. Keine festen Namen wie `cv.typ` oder `coverletter.typ` voraussetzen.
|
||||
- Zum Bauen und Überwachen die Make-Ziele verwenden. Bei Umbenennungen die zentrale Dateikonfiguration im Makefile anpassen.
|
||||
- Die Dokumente liegen als getrennte Varianten in `Admin/` und `Senior Developer/`; PDFs werden neben den jeweiligen Quellen erzeugt. Es gibt nur die drei Befehle `make all`, `make clean` und `make watch`, jeweils für beide Varianten. Gemeinsame Vorlagen und Ressourcen bleiben im übergeordneten Typst-Ordner; deshalb Typst mit `--root .` aus diesem Ordner aufrufen (in den Make-Zielen bereits gesetzt).
|
||||
- Ausschließlich im lokalen Arbeitsordner `/Users/rob/Documents/Job Application` arbeiten; keine Kopien auf SMB-Volumes verwenden.
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
#import "personal.typ": person
|
||||
#import "template.typ": *
|
||||
#import "../personal.typ": person
|
||||
#import "../template.typ": *
|
||||
|
||||
#set page(
|
||||
paper: "a4",
|
||||
@@ -71,4 +71,4 @@ Mit freundlichen Grüßen
|
||||
|
||||
#v(1mm)
|
||||
|
||||
#image("assets/signature.png", width: 25mm)
|
||||
#image("../assets/signature.png", width: 25mm)
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#import "personal.typ": person
|
||||
#import "template.typ": *
|
||||
#import "../personal.typ": person
|
||||
#import "../template.typ": *
|
||||
|
||||
#set page(
|
||||
paper: "a4",
|
||||
+16
-36
@@ -1,50 +1,30 @@
|
||||
.DEFAULT_GOAL := help
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
.PHONY: help all coverletter cv watch watch-coverletter watch-cv clean
|
||||
.PHONY: all clean watch
|
||||
|
||||
TYPST := typst
|
||||
TYPST_FLAGS := --font-path fonts
|
||||
BUILD_DIR := build
|
||||
PYTHON := python3
|
||||
TYPST_FLAGS := --root . --font-path fonts
|
||||
|
||||
# Dateinamen nur hier ändern. Die PDF-Namen werden daraus abgeleitet.
|
||||
COVERLETTER_SRC := Wartenberg-Robert-Anschreiben.typ
|
||||
CV_SRC := Wartenberg-Robert-Lebenslauf.typ
|
||||
COVERLETTER_PDF := $(BUILD_DIR)/$(notdir $(COVERLETTER_SRC:.typ=.pdf))
|
||||
CV_PDF := $(BUILD_DIR)/$(notdir $(CV_SRC:.typ=.pdf))
|
||||
|
||||
help:
|
||||
@echo "Verfügbare Befehle:"
|
||||
@echo " make all Anschreiben und Lebenslauf erzeugen"
|
||||
@echo " make coverletter Nur das Anschreiben erzeugen"
|
||||
@echo " make cv Nur den Lebenslauf erzeugen"
|
||||
@echo " make watch Beide Dokumente bei Änderungen neu bauen"
|
||||
@echo " make watch-coverletter Nur das Anschreiben überwachen"
|
||||
@echo " make watch-cv Nur den Lebenslauf überwachen"
|
||||
@echo " make clean Erzeugte PDFs entfernen"
|
||||
# Leerzeichen schützen, sowohl für Make als auch für die Shell.
|
||||
COVERLETTER_PATHS := Admin/$(COVERLETTER_SRC) Senior\ Developer/$(COVERLETTER_SRC)
|
||||
CV_PATHS := Admin/$(CV_SRC) Senior\ Developer/$(CV_SRC)
|
||||
SOURCES := $(COVERLETTER_PATHS) $(CV_PATHS)
|
||||
PDFS := $(SOURCES:.typ=.pdf)
|
||||
|
||||
all: coverletter cv
|
||||
all: $(PDFS)
|
||||
|
||||
coverletter: $(COVERLETTER_PDF)
|
||||
%.pdf: %.typ personal.typ template.typ Makefile
|
||||
$(TYPST) compile $(TYPST_FLAGS) "$<" "$@"
|
||||
|
||||
cv: $(CV_PDF)
|
||||
$(COVERLETTER_PATHS:.typ=.pdf): assets/signature.png
|
||||
|
||||
watch:
|
||||
@$(MAKE) --no-print-directory -j2 watch-coverletter watch-cv
|
||||
|
||||
watch-coverletter: $(COVERLETTER_SRC) | $(BUILD_DIR)
|
||||
$(TYPST) watch $(TYPST_FLAGS) "$(COVERLETTER_SRC)" "$(COVERLETTER_PDF)"
|
||||
|
||||
watch-cv: $(CV_SRC) | $(BUILD_DIR)
|
||||
$(TYPST) watch $(TYPST_FLAGS) "$(CV_SRC)" "$(CV_PDF)"
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p "$@"
|
||||
|
||||
$(COVERLETTER_PDF): $(COVERLETTER_SRC) personal.typ template.typ assets/signature.png Makefile | $(BUILD_DIR)
|
||||
$(TYPST) compile $(TYPST_FLAGS) "$(COVERLETTER_SRC)" "$@"
|
||||
|
||||
$(CV_PDF): $(CV_SRC) personal.typ template.typ Makefile | $(BUILD_DIR)
|
||||
$(TYPST) compile $(TYPST_FLAGS) "$(CV_SRC)" "$@"
|
||||
watch: $(SOURCES) personal.typ template.typ assets/signature.png
|
||||
@$(PYTHON) watch.py $(TYPST) $(TYPST_FLAGS) -- $(SOURCES)
|
||||
|
||||
clean:
|
||||
rm -f "$(COVERLETTER_PDF)" "$(CV_PDF)"
|
||||
rm -f $(PDFS)
|
||||
@@ -4,9 +4,16 @@ Dieser Ordner ist unabhängig von den LaTeX-Quellen im übergeordneten Projekt.
|
||||
Er enthält die Typst-Dokumente, die gemeinsame Vorlage, alle benötigten Schriften
|
||||
und die Unterschrift.
|
||||
|
||||
Die beiden unabhängig bearbeitbaren Varianten liegen in `Admin/` und
|
||||
`Senior Developer/`. Jedes Verzeichnis enthält ein Anschreiben und einen
|
||||
Lebenslauf als `.typ` sowie die daraus erzeugten PDFs. Beide Varianten wurden
|
||||
zunächst mit den bestehenden Entwicklertexten angelegt; die Admin-Texte können
|
||||
anschließend angepasst werden.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Typst 0.15 oder neuer
|
||||
- Python 3 (für die gebündelte Ausgabe im Watch-Modus)
|
||||
- `make` (optional; die Typst-Befehle können auch direkt ausgeführt werden)
|
||||
|
||||
## PDFs bauen
|
||||
@@ -17,16 +24,18 @@ Im Ordner `07_bewerbung-typst`:
|
||||
make all
|
||||
```
|
||||
|
||||
Die Ergebnisse liegen unter `build/` und tragen den Namen der jeweiligen
|
||||
Typst-Quelldatei mit der Endung `.pdf`.
|
||||
Die vier Ergebnisse liegen direkt neben ihren Typst-Quelldateien in `Admin/`
|
||||
und `Senior Developer/` und tragen denselben Namen mit der Endung `.pdf`.
|
||||
Die PDFs werden von Git ignoriert.
|
||||
|
||||
Einzeln lassen sich die Dokumente mit `make coverletter` und `make cv` bauen.
|
||||
`make all` baut fehlende oder veraltete PDFs. Auch `make` ohne Argumente führt
|
||||
dieses Ziel aus. `make clean` entfernt die vier erzeugten PDFs.
|
||||
|
||||
## Dateien umbenennen
|
||||
|
||||
Die aktuellen Quelldateien stehen ausschließlich in den Variablen
|
||||
Die gemeinsamen Quelldateinamen stehen ausschließlich in den Variablen
|
||||
`COVERLETTER_SRC` und `CV_SRC` am Anfang des `Makefile`.
|
||||
Nach einer Umbenennung diese beiden Angaben entsprechend anpassen.
|
||||
Nach einer Umbenennung in beiden Rollenverzeichnissen diese Angaben entsprechend anpassen.
|
||||
Build, Watch-Modus und PDF-Namen verwenden automatisch diese Konfiguration.
|
||||
Einen laufenden Watch-Modus nach Änderungen am Makefile neu starten.
|
||||
|
||||
@@ -40,15 +49,24 @@ make -nB all
|
||||
|
||||
## Automatisch bei Änderungen bauen
|
||||
|
||||
Der Watch-Modus überwacht beide Dokumente einschließlich ihrer importierten
|
||||
Vorlagen und erzeugt die PDFs nach jeder gespeicherten Änderung neu:
|
||||
Der Watch-Modus baut beim Start alle vier Dokumente und überwacht anschließend
|
||||
ihre Quellen einschließlich der importierten Vorlagen. Bei Änderungen werden
|
||||
nur die betroffenen PDFs neu erzeugt; Änderungen an `personal.typ` oder
|
||||
`template.typ` betreffen alle vier Dokumente:
|
||||
|
||||
```sh
|
||||
make watch
|
||||
```
|
||||
|
||||
Die Überwachung läuft, bis sie mit `Ctrl+C` beendet wird. Einzelne Dokumente
|
||||
lassen sich mit `make watch-coverletter` oder `make watch-cv` überwachen.
|
||||
Die Überwachung läuft, bis sie mit `Ctrl+C` beendet wird. Dabei werden alle
|
||||
vier Watch-Prozesse beendet. Die drei Befehle sind `make all`, `make clean`
|
||||
und `make watch`.
|
||||
`watch.py` bündelt die Ausgabe zeilenweise und stellt jeder Meldung den
|
||||
Dokumentpfad voran, damit gleichzeitige Status- und Fehlermeldungen lesbar bleiben.
|
||||
|
||||
Gemeinsame Kontaktdaten werden in `personal.typ` gepflegt. Farben, Kopf- und
|
||||
Fußzeilen sowie wiederverwendbare CV-Komponenten stehen in `template.typ`.
|
||||
Diese Dateien sowie `fonts/` und `assets/` werden von beiden Varianten gemeinsam
|
||||
verwendet. Das Makefile setzt `--root .`, damit Typst aus den Unterverzeichnissen
|
||||
auf diese Ressourcen zugreifen kann.
|
||||
`personal.typ` und `template.typ` müssen deshalb im Typst-Hauptverzeichnis bleiben.
|
||||
@@ -0,0 +1,74 @@
|
||||
#import "../personal.typ": person
|
||||
#import "../template.typ": *
|
||||
|
||||
#set page(
|
||||
paper: "a4",
|
||||
margin: (left: 20mm, right: 20mm, top: 8mm, bottom: 16mm),
|
||||
footer: cover-footer(person),
|
||||
)
|
||||
|
||||
#show: document-base
|
||||
|
||||
#show link: set text(fill: accent)
|
||||
|
||||
#cover-header(person)
|
||||
|
||||
#v(11mm)
|
||||
|
||||
#grid(
|
||||
columns: (1fr, auto),
|
||||
align: (left, right),
|
||||
[
|
||||
#text(font: "Source Sans Pro", size: 11pt, weight: 700, fill: dark-ink)[
|
||||
ITS Informationstechnik Service GmbH
|
||||
]
|
||||
#v(2pt)
|
||||
#text(font: "Source Sans Pro", size: 9pt, weight: 400, fill: gray-ink)[
|
||||
#smallcaps([Phoenixseestraße 6\
|
||||
44263 Dortmund])
|
||||
]
|
||||
],
|
||||
text(
|
||||
font: "Source Sans Pro",
|
||||
size: 9pt,
|
||||
weight: 300,
|
||||
style: "italic",
|
||||
fill: gray-ink,
|
||||
)[#today-de],
|
||||
)
|
||||
|
||||
#v(13mm)
|
||||
|
||||
#underline(
|
||||
offset: 5pt,
|
||||
text(font: "Source Sans Pro", size: 10pt, weight: 600, fill: dark-ink)[
|
||||
Bewerbung als Senior Softwareentwickler (m/w/d) – C\#
|
||||
],
|
||||
)
|
||||
|
||||
#v(6mm)
|
||||
|
||||
#set text(font: "Source Sans Pro", size: 10pt, weight: 300, fill: gray-ink)
|
||||
#set par(justify: false, leading: 0.7em)
|
||||
|
||||
Sehr geehrtes ITS-Recruiting-Team,
|
||||
|
||||
#v(2.5mm)
|
||||
|
||||
als ausgebildeter Fachinformatiker für Systemintegration sowie Technischer Assistent für Automatisierungs- und Computertechnik verfüge ich über mehr als 25 Jahre Erfahrung in Softwareentwicklung und Qualitätssicherung. Bei der ITS Gruppe reizt mich besonders die Entwicklung anspruchsvoller Software für Netzbetreiber.
|
||||
|
||||
Seit 2019 entwickle und betreue ich komplexe Anwendungen mit C\# und .NET in mehr als 20 Unity-Projekten, von der Architektur über die Implementierung bis hin zu Betrieb und Wartung. Zu meinem Alltag gehören objektorientierte Programmierung, die Entwicklung von Benutzeroberflächen und Geschäftslogik, die Integration externer Systeme und Schnittstellen, CI-Pipelines mit GitHub Actions sowie die Arbeit in agilen Teams (Scrum, Jira). Ihre Kundenwelt ist mir bereits vertraut: Für enviaM habe ich ein VR-Training umgesetzt, das Umspannwerksabläufe mit Schrittsteuerung, Spannungsprüfung und Fehlererkennung abbildet und für TenneT entwickelte ich eigene TypeScript-Komponenten einer mehrsprachigen Web- und WebXR-Visualisierung. Auch GIS-Themen sind mir aus meiner Open-Data-Arbeit und eigenen Kartenprojekten mit Leaflet und GeoJSON vertraut. TypeScript und moderne Webtechnologien setze ich sicher ein, etwa für mehrsprachige Web- und WebXR-Anwendungen, für Firmenwebseiten sowie zur Einbettung von Unity-WebGL-Anwendungen. Erfahrung mit relationalen Datenbanken bringe ich aus der Entwicklung und Migration von Web- und Warenwirtschaftssystemen als selbstständiger Full-Stack-Developer mit. Fachliche Anforderungen gemeinsam zu klären und in wartbare Software zu übersetzen, ist mir besonders wichtig. Im geförderten Projekt VISOR/OProc entwarf und entwickelte ich in Zusammenarbeit mit Forschenden der HTW Dresden ein offenes Datenmodell und ein Werkzeug zur Prozessvisualisierung.
|
||||
|
||||
Solide Erfahrungen in spezifikationsgetriebener, KI-gestützter Softwareentwicklung habe ich bereits in mehreren Kundenprojekten mit C\#, Unity und Python gesammelt. Für einen AssetDownloader der MMS konzipierte ich eine eigenständige .NET-Standard-Kernbibliothek mit separater Unity-Anbindung und setzte diese testgetrieben mit KI-Unterstützung um. Automatisierte Tests mit NUnit, Moq und HTTP-Mocks sichern unter anderem Download-Abbrüche, Wiederaufnahme und Cache-Verhalten ab.
|
||||
|
||||
In Lovion BIS möchte ich mich fachlich und technisch gründlich einarbeiten und anschließend meine Erfahrung mit modularer Architektur, Schnittstellen und automatisierten Tests in die Weiterentwicklung einbringen. Ich arbeite eigenverantwortlich mit hohem Qualitätsanspruch und schätze sowohl eine offene Kommunikation auf Deutsch und Englisch als auch die Zusammenarbeit in flachen, agilen Strukturen. Sehr gern würde ich direkt am Standort Dresden oder mobil arbeiten. Meine Gehaltsvorstellung liegt bei rund 60.000 € brutto jährlich für eine 40-Stunden-Woche.
|
||||
|
||||
Mein frühestmöglicher Eintrittstermin ist der 1. Oktober 2026. Ich freue mich auf ein persönliches Gespräch, um mehr über Ihre Produkte, die Lovion-BIS-Plattform und Ihr Entwicklungsteam zu erfahren.
|
||||
|
||||
#v(1mm)
|
||||
|
||||
Mit freundlichen Grüßen
|
||||
|
||||
#v(1mm)
|
||||
|
||||
#image("../assets/signature.png", width: 25mm)
|
||||
@@ -0,0 +1,229 @@
|
||||
#import "../personal.typ": person
|
||||
#import "../template.typ": *
|
||||
|
||||
#set page(
|
||||
paper: "a4",
|
||||
margin: (left: 14mm, right: 14mm, top: 8mm, bottom: 16mm),
|
||||
footer: cv-footer(person),
|
||||
)
|
||||
|
||||
#show: document-base
|
||||
#set par(leading: 0.56em)
|
||||
|
||||
|
||||
#cv-header(person)
|
||||
|
||||
#section("Ber", "ufserfahrung")
|
||||
|
||||
#entry(
|
||||
"C# Developer & Software Engineer for Unity AR/VR",
|
||||
"vr-bits GmbH",
|
||||
"Leipzig",
|
||||
"seit 2019",
|
||||
(
|
||||
[Mehr als 20 C\#-Anwendungen mit Unity für Web, Desktop, Mobile und XR
|
||||
#list( marker: [•], indent: 8pt, body-indent: 4pt, spacing: 6pt,
|
||||
[Projektkonzeption, Entwicklung, Deployment und Betreuung],
|
||||
[Integration von SDKs, Paketen und externen Services in Unity; Implementierung von Schnittstellen und Kapselung externer Abhängigkeiten],
|
||||
[Versions- und Paketpflege, technische Fehleranalyse, Performance-Optimierung und automatisierte Tests],
|
||||
)
|
||||
],
|
||||
[TenneT 2GW Platform: eigene TypeScript-Komponenten für eine mehrsprachige Web-/WebXR-Visualisierung],
|
||||
[enviaM: zustandsbasierte Trainingslogik für Umspannwerksabläufe mit Spannungsprüfung und Fehlererkennung],
|
||||
[
|
||||
AssetDownloader für MMS
|
||||
#list( marker: [•], indent: 8pt, body-indent: 4pt, spacing: 6pt,
|
||||
[Anforderungserhebung und Konzeption einer eigenständigen .NET-Standard-Kernbibliothek mit separater Unity-Anbindung],
|
||||
[Implementierung paralleler asynchroner Downloads mit Wiederaufnahmefunktion und Cache-Verwaltung],
|
||||
[Testgetriebene Umsetzung mit NUnit, Moq und HTTP-Mocks; Tests für Download-Abbruch und -Wiederaufnahme, Dateiintegrität und Cache-Verhalten],
|
||||
)
|
||||
],
|
||||
[
|
||||
Roche – Sicherheitstraining für Laborschleusen
|
||||
#list( marker: [•], indent: 8pt, body-indent: 4pt, spacing: 6pt,
|
||||
[Entwicklung modularer Trainingsabläufe mit zustandsbasierter Ablaufsteuerung und persistenter Lernfortschrittsverwaltung],
|
||||
[Entwicklung von Editor-Werkzeugen zur datengetriebenen Erzeugung von Trainingsinhalten aus strukturierten Kundenvorgaben],
|
||||
[Refactoring bestehender Interaktionskomponenten zur Verbesserung der Wartbarkeit],
|
||||
[Integration als SCORM-Paket in Lernsystem und implementation einer C\#-/JavaScript-Brücke zur Übertragung der Lernstände],
|
||||
[Automatisierung von WebGL-Builds und Deployments mit GitHub Actions und GameCI],
|
||||
)
|
||||
],
|
||||
[
|
||||
VR-TrainingGenerator
|
||||
#list( marker: [•], indent: 8pt, body-indent: 4pt, spacing: 6pt,
|
||||
[Ausgliederung und Weiterentwicklung eines wiederverwendbaren Unity-Pakets für die Trainingsgenerierung],
|
||||
[Entwicklung eines UI-Toolkit-basierten Editor-Wizards zur konfigurationsgestützten Erzeugung von Trainingsszenen],
|
||||
[CLI-/Batchmode-Verarbeitung und NUnit-Regressionstests],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Freelance Full-Stack Developer",
|
||||
"Selbständig",
|
||||
"Dresden",
|
||||
"2017–2019",
|
||||
(
|
||||
[Entwicklung von E-Commerce- und Warenwirtschaftssystemen mit PHP, JavaScript und MySQL, unter anderem mit Shopware],
|
||||
[Migration komplexer Systeme und Datenbanken],
|
||||
[Frontend-Entwicklung mit JavaScript-Frameworks sowie technische Beratung],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Hauptentwickler und Projektkoordinator",
|
||||
"VISOR/OProc – Prototype Fund",
|
||||
"Dresden",
|
||||
"2017–2018",
|
||||
(
|
||||
[Anforderungserhebung mit Forschenden der HTW Dresden im BMBF-geförderten Projekt],
|
||||
[Entwurf eines offenen Datenmodells für Stadtentwicklungsprozesse],
|
||||
[Konzeption und Entwicklung interaktiver Prozessvisualisierungen mit Preact, Redux, SVG und Dagre],
|
||||
[Umsetzung gekoppelter Zeitachsen-, Graph-, Filter- und Detailansichten],
|
||||
[Abstimmung und Priorisierung fachlicher Anforderungen sowie Koordination der technischen Umsetzung im Projektteam],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Software-Qualitätssicherung – Webentwicklung",
|
||||
"MAGIX Development AG",
|
||||
"Dresden",
|
||||
"2006–2016",
|
||||
(
|
||||
[Automatisierung von GUI-Tests mit SikuliX für Windows-Anwendungen mit WPF- und Qt-5-Oberflächen],
|
||||
[Softwaretest und Qualitätssicherung sowie strukturierte Analyse von Anwendungsfehlern],
|
||||
[Interne Webentwicklungsprojekte, IT-Support und Systemadministration],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Webentwickler",
|
||||
"Nebenberuflich",
|
||||
"Dresden",
|
||||
"2012–2017",
|
||||
(
|
||||
[Entwicklung von E-Commerce- und Warenwirtschaftssystemen mit PHP, JavaScript und MySQL],
|
||||
[Entwurf und Optimierung relationaler Datenbanken sowie Entwicklung responsiver Benutzeroberflächen nach dem Mobile-First-Prinzip],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Server Support",
|
||||
"Compaq Computer Corporation",
|
||||
"München",
|
||||
"2001-2002",
|
||||
(
|
||||
[Technischer First-Level-Support für Serverprodukte],
|
||||
),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
#cv-header(person)
|
||||
|
||||
#section("Tec", "hnische Kenntnisse")
|
||||
|
||||
#skills[
|
||||
#skill("C# & .NET", [
|
||||
C\#, .NET Standard, asynchrone Verarbeitung mit kontrollierter
|
||||
Parallelität, ereignisbasierte Kommunikation, Fehler- und
|
||||
Abbruchbehandlung, HTTP-Streaming mit HttpClient
|
||||
])
|
||||
#skill("Architektur & Integration", [
|
||||
Trennung von Kernlogik und Framework-Anbindung, modulare
|
||||
Bibliotheken und Pakete, zustandsbasierte Ablaufsteuerung,
|
||||
Caching und Datenvalidierung, REST/HTTP, OpenAPI, JSON, XML
|
||||
])
|
||||
#skill("Unity & Entwicklungswerkzeuge", [
|
||||
Komponentenentwicklung, ScriptableObjects, Assembly Definitions,
|
||||
Editor-Erweiterungen mit UI Toolkit, datengetriebene
|
||||
Szenengenerierung, CLI-/Batchmode-Automatisierung
|
||||
])
|
||||
#skill("Tests & Qualität", [
|
||||
Testgetriebene Entwicklung, Unit-, Integrations- und
|
||||
Regressionstests, Mocking und HTTP-Testdoubles,
|
||||
NUnit, Moq, Pytest, GUI-Testautomatisierung mit SikuliX
|
||||
])
|
||||
|
||||
#skill("Web & Benutzeroberflächen", [
|
||||
TypeScript, Python/Django, Jekyll, PHP, JavaScript, HTML/CSS, Three.js, Preact/Redux
|
||||
])
|
||||
#skill("Datenbanken & Geodaten", [SQL, MySQL, SQLite, Datenmodellierung, Datenbankmigrationen, Django ORM, Leaflet, GeoJSON])
|
||||
#skill("Delivery & Werkzeuge", [Git, GitHub Actions, GameCI, Docker/Compose, automatisierte Builds und Deployments])
|
||||
#skill("Methoden & Zusammenarbeit", [Anforderungserhebung, Scrum, Jira, technische Dokumentation, spezifikationsgetriebene und KI-gestützte Softwareentwicklung])
|
||||
#skill("Infrastruktur & Betrieb", [Linux, Windows, macOS, NixOS, Shell, nginx, Netzwerkdiagnose, Backup und Wiederherstellung])
|
||||
]
|
||||
|
||||
#section("Aus", "bildung")
|
||||
|
||||
#entry(
|
||||
"Fachinformatiker für Systemintegration",
|
||||
"BSZET Dresden / MAGIX GmbH",
|
||||
"Dresden",
|
||||
"2003–2006",
|
||||
(
|
||||
[Systemintegration, Anwendungsentwicklung und Geschäftsprozesse],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Technischer Assistent für Automatisierungs- und Computertechnik",
|
||||
"Berufliches Schulzentrum Weißwasser",
|
||||
"Weißwasser",
|
||||
"1997–2000",
|
||||
(
|
||||
[Programmierung, Automatisierungstechnik sowie Hardware- und Softwareentwicklung],
|
||||
[Rechentechnik, Mess- und Regelungstechnik sowie CAD],
|
||||
),
|
||||
)
|
||||
|
||||
#section("Eng", "agement & Mentoring")
|
||||
|
||||
#entry(
|
||||
"Mentor & Jury-Mitglied",
|
||||
"Jugend hackt Dresden",
|
||||
"Dresden",
|
||||
"seit 2015",
|
||||
(
|
||||
[Mentoring bei Coding-Projekten und Jury-Tätigkeit bei Hackathons],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Dozent & Workshop-Leiter",
|
||||
"Chaos macht Schule",
|
||||
"Sachsen",
|
||||
"2014–2018",
|
||||
(
|
||||
[Programmier-Workshops sowie Vermittlung von Datenschutz und IT-Sicherheit an Schulen],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Lead",
|
||||
"Open Data Dresden",
|
||||
"Dresden",
|
||||
"2014–2021",
|
||||
(
|
||||
[Organisation von Community-Aktivitäten und Open-Data-Projekten; Gründung eines Open-Data-Labs mit der Open Knowledge Foundation],
|
||||
),
|
||||
)
|
||||
|
||||
#entry(
|
||||
"Speaker",
|
||||
"Web Montag Dresden, CCC Veranstaltungen",
|
||||
"Dresden",
|
||||
"2012–2019",
|
||||
(
|
||||
[Vorträge zu Webentwicklung und IT-Trends sowie Wissensaustausch in der Developer-Community],
|
||||
),
|
||||
)
|
||||
|
||||
#section("Per", "sönliches")
|
||||
|
||||
#v(1em)
|
||||
|
||||
#set text(font: "Source Sans Pro", size: 9pt, weight: 300, fill: ink)
|
||||
Meine Familie ist mein wichtigster Rückhalt. In meiner Freizeit zieht es mich besonders in die Berge oder aufs Wasser. Wenn daneben noch Zeit bleibt, widme ich mich gern der Musik.
|
||||
Als begeisterter Autodidakt erschließe ich mir beruflich wie privat neue Technologien und Programmiersprachen.
|
||||
Im Team schätze ich einen offenen, respektvollen Austausch. Unterschiedliche Perspektiven helfen mir, neue Zusammenhänge zu erkennen und gemeinsam tragfähige Lösungen zu entwickeln.
|
||||
@@ -0,0 +1,72 @@
|
||||
"""Run Typst watchers with readable, document-specific output."""
|
||||
|
||||
from pathlib import Path
|
||||
from queue import Empty, Queue
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from threading import Thread
|
||||
|
||||
|
||||
def relay(process, label, messages):
|
||||
with process.stdout:
|
||||
for line in process.stdout:
|
||||
messages.put((label, line.rstrip()))
|
||||
messages.put((label, None))
|
||||
|
||||
|
||||
def interrupted(signum, frame):
|
||||
raise KeyboardInterrupt
|
||||
|
||||
|
||||
def main():
|
||||
separator = sys.argv.index("--")
|
||||
executable, *flags = sys.argv[1:separator]
|
||||
sources = sys.argv[separator + 1:]
|
||||
messages = Queue()
|
||||
processes = []
|
||||
signal.signal(signal.SIGTERM, interrupted)
|
||||
try:
|
||||
for source in sources:
|
||||
process = subprocess.Popen(
|
||||
[executable, "watch", *flags, source, str(Path(source).with_suffix(".pdf"))],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
start_new_session=True,
|
||||
)
|
||||
processes.append(process)
|
||||
Thread(target=relay, args=(process, source, messages), daemon=True).start()
|
||||
while True:
|
||||
try:
|
||||
label, line = messages.get(timeout=0.2)
|
||||
except Empty:
|
||||
continue
|
||||
if line is None:
|
||||
print(f"[{label}] Watch-Prozess unerwartet beendet.", file=sys.stderr)
|
||||
return 1
|
||||
if line:
|
||||
print(f"[{label}] {line}", flush=True)
|
||||
except KeyboardInterrupt:
|
||||
print("\nÜberwachung beendet.", flush=True)
|
||||
return 0
|
||||
except OSError as error:
|
||||
print(f"Watch konnte nicht gestartet werden: {error}", file=sys.stderr)
|
||||
return 1
|
||||
finally:
|
||||
# Stop all watchers, including when startup fails partway through.
|
||||
for process in processes:
|
||||
if process.poll() is None:
|
||||
process.terminate()
|
||||
for process in processes:
|
||||
try:
|
||||
process.wait(timeout=3)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
process.wait()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user