<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Creatronix</title>
	<atom:link href="https://creatronix.de/feed/" rel="self" type="application/rss+xml" />
	<link>https://creatronix.de/</link>
	<description>My adventures in code &#38; business</description>
	<lastBuildDate>Fri, 03 Apr 2026 13:53:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>M-shaped Personality</title>
		<link>https://creatronix.de/m-shaped-personality/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 13:21:50 +0000</pubDate>
				<category><![CDATA[Business & Management]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7974</guid>

					<description><![CDATA[<p>Eine meiner Lieblingsbands ist Linkin Park. Als Chester Bennington 2017 gestorben ist, dachte wohl kaum jemand ernsthaft an ein Comeback. Zu prägend war seine Stimme für den Sound der Band. Als Sänger war er das Aushängeschild. Wenn man ihn hörte, wusste man sofort: Das ist Linkin Park. Dann kam 2024 das große Comeback – mit&#8230;</p>
<p>The post <a href="https://creatronix.de/m-shaped-personality/">M-shaped Personality</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Eine meiner Lieblingsbands ist Linkin Park.</p>
<p>Als Chester Bennington 2017 gestorben ist, dachte wohl kaum jemand ernsthaft an ein Comeback. Zu prägend war seine Stimme für den Sound der Band. Als Sänger war er das Aushängeschild. Wenn man ihn hörte, wusste man sofort: Das ist Linkin Park.</p>
<p>Dann kam 2024 das große Comeback – mit der neuen Sängerin Emily Armstrong. Wie konnte das funktionieren? Und was hat das mit einer M-Shaped Personality zu tun?</p>
<p>Gehen wir es der Reihe nach an:</p>
<p>Die Stimme von Chester Bennington war ein klassisches „I“: eine klar erkennbare, außergewöhnlich starke Fähigkeit. Sicherlich basierte sie auf Talent und besonderen körperlichen Voraussetzungen, wurde aber über Jahre hinweg durch Übung und Erfahrung immer weiter verfeinert. Seine Stimme hat den Sound der Band massiv geprägt.</p>
<p>Aber warum funktioniert Linkin Park auch mit einer neuen Stimme noch? Weil die Stimme eben nicht das einzige Element ist, das den Sound der Band ausmacht.</p>
<p>Hinter den Kulissen ist <a href="https://www.mikeshinoda.com/">Mike Shinoda</a> aus meiner Sicht der eigentliche Strippenzieher – und ein gutes Beispiel für eine M-Shaped Personality.</p>
<p>Warum? Schaut man sich zum Beispiel den Wikipedia-Eintrag an, hat fast jedes Bandmitglied eine klar definierte Rolle. Mike Shinoda dagegen vereint gleich mehrere: Rap, Keyboard, Gitarre, Sampler, Piano, Gesang. Dazu kommt laut Discogs seine Arbeit als Producer und Co-Producer.</p>
<p>Er beherrscht extrem viele Dinge. Viele davon sehr gut – aber vielleicht keines davon auf absolutem Weltklasse-Niveau für sich allein betrachtet.</p>
<p>Ist er der beste Rapper der Welt? Nein.<br />
Der beste Keyboarder? Auch nicht.<br />
Der beste Songwriter? Wahrscheinlich nicht.<br />
Der beste Produzent? Vermutlich ebenfalls nicht.</p>
<p>Aber er ist in all diesen Bereichen gut genug, und genau diese Kombination macht den Unterschied. Zusammengenommen bilden diese Fähigkeiten das kreative Rückgrat der Band. Wenn man einen Linkin-Park-Song hört, erkennt man oft schon sehr früh, dass es ein Song dieser Band ist – noch bevor der Hauptgesang überhaupt einsetzt.</p>
<p>Will ich damit die Beiträge der anderen Bandmitglieder kleinreden? Natürlich nicht. Für das Comeback war auch die ausdrucksstarke Stimme von Emily Armstrong entscheidend. Und selbstverständlich haben auch die anderen Mitglieder den Sound der Band geprägt und prägen ihn bis heute.</p>
<p>Aber irgendjemand musste sich auf die Suche nach einer neuen Sängerin machen. Irgendjemand musste daran glauben, dass die Geschichte der Band noch nicht zu Ende ist. Irgendjemand musste vermutlich noch ein ganzes Backlog an Songideen im Kopf oder in der Schublade haben.</p>
<p>Und wie bekomme ich jetzt die Kurve zurück zu Technologie und Robotics?</p>
<p>Ganz einfach: In einer Zeit, in der moderne AI-Tools immer stärker die Rolle von Spezialisten übernehmen, braucht es zur Koordination weiterhin diese M-Shaped Personalities – so jedenfalls die landläufige Meinung. Irgendjemand muss diese Spezialisten anleiten, sinnvoll einsetzen und überhaupt erst auf die Idee kommen, welches Ziel es sich zu verfolge lohnt.</p>
<p>Dieser Jemand muss nicht in allem der absolute Top-Experte sein. Es reicht, wenn er ein System aufbauen kann und an den entscheidenden Stellen seine eigenen Fähigkeiten einbringt, um daraus ein starkes Zusammenspiel aus Menschen und Agenten zu formen</p>
<p>Lassen wir dazu einmal <a href="https://jurgenappelo.com/">Jürgen Appelo</a> zu Wort kommen:</p>
<blockquote><p>But as AI takes on more complex, specialized tasks, the ability to synthesize information from different fields becomes crucial. The goal is to become M-shaped, combining mastery across multiple fields with strong business and leadership skills.</p></blockquote>
<p>Auf Deutsch:</p>
<blockquote><p>Aber wenn AI komplexere, spezialisierte Aufgaben übernimmt, wird die Fähigkeit, Informationen aus verschiedenen Bereichen zu synthetisieren, entscheidend. Das Ziel ist es, M-förmig zu werden: also Kompetenzen in mehreren Disziplinen mit starken Business- und Leadership-Skills zu verbinden.</p></blockquote>
<p>Dröseln wir diese Modelle noch etwas weiter auf:</p>
<p><strong>I-Shaped Personality</strong></p>
<p>Das ist das, was man früher oft etwas abfällig als „Fachidiot“ bezeichnet hat. Wohlwollender gesagt: jemand mit extrem tiefer Expertise in einem Gebiet, aufgebaut über viele Jahre oder Jahrzehnte. Diese Tiefe geht allerdings manchmal<br />
zulasten von Breite, Kontextverständnis oder sozialen Fähigkeiten. Archetyp Magnus Carlsen</p>
<p><strong>T-Shaped Personality</strong></p>
<p>Hier kombiniert jemand eine sehr starke Kernkompetenz mit einem breiten Überblick über angrenzende Disziplinen. Also: ein tiefes Spezialgebiet plus ausreichend Breite, um mit anderen Feldern gut zusammenzuarbeiten. Archetyp Casey Neistat</p>
<p><strong>Pi-Shaped Personality</strong></p>
<p>Ein Pi π hat zwei „Beine“ – also tiefes Wissen in zwei unterschiedlichen Bereichen. Das erhöht den eigenen Wert oft erheblich, weil die Kombination zweier echter Kompetenzen deutlich seltener ist als reine Einzeldisziplinen. Archetyp Richard Feynman (Pädagogik und Physik)</p>
<p><strong>M-Shaped Personality</strong></p>
<p>Ein M hat mehrere Säulen. Es steht für tiefes Wissen in mindestens drei relevanten Bereichen – kombiniert mit der Fähigkeit, diese sinnvoll zusammenzubringen und in Wirkung zu übersetzen.</p>
<p>Und genau deshalb ist dieses Modell heute so interessant: Nicht, weil Spezialisten unwichtig werden &#8211; im Gegenteil. Sondern weil in einer Welt voller hochspezialisierter Menschen und immer leistungsfähigerer AI-Tools diejenigen besonders wertvoll werden, die mehrere Disziplinen verbinden, Teams orchestrieren und aus vielen Einzelteilen ein funktionierendes Ganzes bauen können.</p>
<p>Vielleicht ist genau das der eigentliche Kern der Geschichte von Linkin Park: Nicht nur eine außergewöhnliche Stimme, sondern ein System aus mehreren kreativen Kräften – zusammengehalten von jemandem, der genug von vielen Disziplinen versteht, um daraus etwas Eigenes, Wiedererkennbares und Neues entstehen zu lassen.</p>
<p>The post <a href="https://creatronix.de/m-shaped-personality/">M-shaped Personality</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Das große Git-Tutorial</title>
		<link>https://creatronix.de/das-grose-git-tutorial/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Thu, 26 Mar 2026 20:10:53 +0000</pubDate>
				<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7965</guid>

					<description><![CDATA[<p>Motivation Jeder kennt und nutzt Git. Es gibt bis auf Ausnahmen (ich schaue dich an, Perforce) keine ernstzunehmenden Alternativen mehr. Ich lasse Azubis ab der ersten Woche schon mit Git arbeiten, allerdings zunächst im Kontext einer IDE, damit sie ihren Code entspannt versionieren können. Im zweiten Lehrjahr gibt es dann den Blick hinter die Kulissen,&#8230;</p>
<p>The post <a href="https://creatronix.de/das-grose-git-tutorial/">Das große Git-Tutorial</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Jeder kennt und nutzt Git. Es gibt bis auf Ausnahmen (ich schaue dich an, Perforce) keine ernstzunehmenden Alternativen mehr.</p>
<p>Ich lasse Azubis ab der ersten Woche schon mit Git arbeiten, allerdings zunächst im Kontext einer IDE,<br />
damit sie ihren Code entspannt versionieren können.</p>
<p>Im zweiten Lehrjahr gibt es dann den Blick hinter die Kulissen, also auf die Kommandozeile.</p>
<h2>Inhalt</h2>
<ul>
<li>Basics: Installation, Konfiguration, Repository erstellen, Status &amp; Log, Commits, .gitignore, Remote, Fetch &amp; Pull</li>
<li>Intermediate: Branching, Merging, Merge-Konflikte, Stash, Diff, Tags</li>
<li>Advanced: Rebase, Squashen von Commits, Cherry-Pick, Reflog, Bisect</li>
</ul>
<h2>Voraussetzungen</h2>
<ul>
<li>Ein Terminal / eine Shell (bash, zsh, PowerShell, …)</li>
<li>Grundlegende Erfahrung mit der Kommandozeile (cd, mkdir, ls/dir)</li>
<li>Optional: ein GitHub- oder GitLab-Account für Remote-Repositories</li>
</ul>
<h2>Basics</h2>
<h3>Installation</h3>
<p>Damit etwas unter Versionskontrolle gestellt werden kann, muss Git zuerst installiert sein.</p>
<p><strong>Windows:</strong></p>
<p>Download von <a href="https://git-scm.com/download/win">https://git-scm.com/download/win</a> und Installer ausführen</p>
<p><strong>Linux (Debian/Ubuntu):</strong></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo apt install git</code></pre>
</div>
<p><strong>macOS:</strong></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>brew install git</code></pre>
</div>
<p>Wir können nun testen, ob die Installation erfolgreich war:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git --version</code></pre>
</div>
<h3>Konfiguration</h3>
<p>Bevor wir loslegen, teilen wir Git unseren Namen und unsere E-Mail-Adresse mit.<br />
Diese Infos werden in jedem Commit gespeichert.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git config --global user.name "Dein Name"
git config --global user.email "deine@email.de"</code></pre>
</div>
<p>Optional – Standardbranch auf <code>main</code> setzen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git config --global init.defaultBranch main</code></pre>
</div>
<h3>Repository erstellen (<code>init</code>)</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>mkdir my_workspace
cd my_workspace
git init</code></pre>
</div>
<p>Damit haben wir ein leeres Git-Repository. Jetzt legen wir die ersten Dateien an:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>touch .gitignore
touch README.md
touch app.py</code></pre>
</div>
<h3>Status &amp; Log</h3>
<p>Zwei Befehle, die man ständig braucht sind:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git status # Zeigt den aktuellen Zustand des Repositories
git log # Zeigt die Commit-Historie
git log --oneline # Kompakte Einzeiler-Ansicht</code></pre>
</div>
<h3>Staging &amp; Commit</h3>
<p>Dateien müssen zunächst in die Staging Area und können dann committet werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git add . # Alle Änderungen stagen
git add README.md # Einzelne Datei stagen
git commit -m "initial commit" # Commit mit Nachricht</code></pre>
</div>
<p><strong>Tipp:</strong> Gute Commit-Messages beschreiben <em>was</em> und <em>warum</em>, nicht <em>wie</em>.</p>
<p>&nbsp;</p>
<h3><img fetchpriority="high" decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/git-init-add-commit.png" alt="" width="1010" height="275" class="alignnone size-full wp-image-7962" srcset="https://creatronix.de/wp-content/uploads/2026/03/git-init-add-commit.png 1010w, https://creatronix.de/wp-content/uploads/2026/03/git-init-add-commit-300x82.png 300w, https://creatronix.de/wp-content/uploads/2026/03/git-init-add-commit-768x209.png 768w" sizes="(max-width: 1010px) 100vw, 1010px" /></h3>
<h3>.gitignore</h3>
<p>Die Datei <code>.gitignore</code> definiert, welche Dateien Git ignorieren soll (Build-Artefakte, IDE-Konfiguration, Secrets, …):</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code># Beispiel .gitignore
pycache/
*.pyc
.idea/
.env
build/
</code></pre>
</div>
<h3>Remote hinzufügen und pushen</h3>
<p>Ein Remote-Repository (z. B. auf GitHub) wird so verknüpft:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git remote add origin https://github.com/user/repo.git
git push -u origin main</code></pre>
</div>
<p><code>-u</code> setzt das Upstream-Tracking, sodass <code>git push</code> danach ohne weitere Argumente funktioniert.</p>
<h3>Änderungen vom Remote holen</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git fetch # Holt Änderungen, merged aber NICHT
git pull # Holt Änderungen UND merged in den aktuellen Branch</code></pre>
</div>
<p><strong>Faustregel:</strong> <code>fetch</code> ist sicher und unverbindlich, <code>pull</code> verändert den lokalen Branch.</p>
<h2>Intermediate</h2>
<h3>Remote-Repo clonen</h3>
<p>Statt ein Repository von Grund auf neu zu erstellen, kannst du ein bestehendes Remote-Repository mit <code>git clone</code> auf den eigenen Rechner kopieren.<br />
Dabei passiert automatisch einiges:</p>
<ol>
<li>Ein neuer Ordner mit dem Repository-Namen wird erstellt</li>
<li>Die gesamte Historie (alle Commits, Branches, Tags) wird heruntergeladen</li>
<li>Ein Remote namens <code>origin</code> wird angelegt, der auf die Quell-URL zeigt</li>
<li>Der Standard-Branch (z. B. <code>main</code>) wird ausgecheckt</li>
</ol>
<p><strong>Grundsyntax:</strong></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git clone https://github.com/user/repo.git</code></pre>
</div>
<p><strong>Einen bestimmten Branch clonen:</strong></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git clone -b develop https://github.com/user/repo.git</code></pre>
</div>
<p>Damit wird direkt der Branch <code>develop</code> ausgecheckt, nützlich, wenn du nicht auf <code>main</code> arbeiten möchtest.</p>
<p><strong>Tipp:</strong> Nach dem Clonen kannst du dir den eingerichteten Remote anzeigen lassen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd repo
git remote -v

#origin https://github.com/user/repo.git (fetch)
#origin https://github.com/user/repo.git (push)</code></pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/git-workflow.png" alt="" width="842" height="202" class="alignnone size-full wp-image-7961" srcset="https://creatronix.de/wp-content/uploads/2026/03/git-workflow.png 842w, https://creatronix.de/wp-content/uploads/2026/03/git-workflow-300x72.png 300w, https://creatronix.de/wp-content/uploads/2026/03/git-workflow-768x184.png 768w" sizes="(max-width: 842px) 100vw, 842px" /></h3>
<h3>Branching</h3>
<p>Branches sind einer der größten Vorteile von Git. Sie erlauben paralleles Arbeiten an Features, Bugfixes usw.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git branch # Alle lokalen Branches anzeigen
git branch feature/login # Neuen Branch erstellen
git checkout feature/login # In den Branch wechseln
git checkout -b feature/login # Erstellen + Wechseln in einem Schritt</code></pre>
</div>
<h3><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/git-remote-branch.png" alt="" width="911" height="290" class="alignnone size-full wp-image-7963" srcset="https://creatronix.de/wp-content/uploads/2026/03/git-remote-branch.png 911w, https://creatronix.de/wp-content/uploads/2026/03/git-remote-branch-300x95.png 300w, https://creatronix.de/wp-content/uploads/2026/03/git-remote-branch-768x244.png 768w" sizes="(max-width: 911px) 100vw, 911px" /></h3>
<h3>Merging</h3>
<p>Wenn ein Feature fertig ist, wird der Branch zurück in <code>main</code> gemerged:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git checkout main
git merge feature/login</code></pre>
</div>
<h3>Merge-Konflikte</h3>
<p>Wenn zwei Branches dieselbe Stelle in einer Datei geändert haben, entsteht ein Merge-Konflikt.<br />
Git markiert die betroffenen Stellen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Deine Änderung
=======
Änderung aus dem anderen Branch
&gt;&gt;&gt;&gt;&gt;&gt;&gt; feature/login</code></pre>
</div>
<p>Lösung: Datei manuell bereinigen, dann:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git add &lt;datei&gt;
git commit</code></pre>
</div>
<h3>Stash</h3>
<p>Unfertige Änderungen kann man zwischenspeichern, ohne zu committen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git stash # Änderungen wegstashen
git stash list # Alle Stashes anzeigen
git stash pop # Letzten Stash wiederherstellen und entfernen
git stash apply # Letzten Stash wiederherstellen, aber behalten</code></pre>
</div>
<h3>Diff</h3>
<p>Änderungen anzeigen lassen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git diff # Unstaged-Änderungen
git diff --staged # Staged-Änderungen (vor dem Commit)
git diff main..feature # Unterschied zwischen zwei Branches</code></pre>
</div>
<h3>Tags</h3>
<p>Releases oder Meilensteine markieren:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git tag v1.0.0
git tag -a v1.0.0 -m "Erstes Release"
git push origin v1.0.0</code></pre>
</div>
<h2>Advanced</h2>
<h3>Rebase</h3>
<p>Rebase schreibt die Commit-Historie um und setzt Commits auf eine neue Basis.<br />
Nützlich, um einen sauberen, linearen Verlauf zu erzeugen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git checkout feature/login
git rebase main</code></pre>
</div>
<p>&nbsp;</p>
<p><strong><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/git-rebase.png" alt="" width="685" height="202" class="alignnone size-full wp-image-7964" srcset="https://creatronix.de/wp-content/uploads/2026/03/git-rebase.png 685w, https://creatronix.de/wp-content/uploads/2026/03/git-rebase-300x88.png 300w" sizes="(max-width: 685px) 100vw, 685px" /></strong></p>
<p><strong>Achtung:</strong> Rebase verändert die Historie. Deshalb nicht auf bereits gepushten, geteilten Branches verwenden.</p>
<h3>Squashen von Commits</h3>
<p>Mehrere Commits zu einem zusammenfassen (z. B. vor einem Merge Request):</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git rebase -i HEAD~3 # Die letzten 3 Commits interaktiv bearbeiten</code></pre>
</div>
<p>Im Editor dann <code>pick</code> für die gewünschten Commits durch <code>squash</code> (oder <code>s</code>) ersetzen.</p>
<h3>Cherry-Pick</h3>
<p>Einen einzelnen Commit aus einem anderen Branch übernehmen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git cherry-pick &lt;commit-hash&gt;</code></pre>
</div>
<h3>Reflog</h3>
<p>Das Sicherheitsnetz: Zeigt <em>alle</em> Aktionen, auch nach einem versehentlichen Reset:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>git reflog
git checkout &lt;hash&gt; # Verlorenen Stand wiederherstellen</code></pre>
</div>
<h2>Fazit</h2>
<p>Git ist ein mächtiges Werkzeug. Die Basics reichen für den Alltag, aber wer Rebase, Squash und Bisect beherrscht,<br />
kann auch in komplexen Projekten souverän arbeiten.</p>
<p><strong>Weiterführende Ressourcen:</strong></p>
<ul>
<li><a href="https://learngitbranching.js.org/?locale=de_DE">Git Branching interaktiv lernen</a></li>
<li><a href="https://git-scm.com/book/de/v2">Pro Git Book (kostenlos)</a></li>
<li><a href="https://education.github.com/git-cheat-sheet-education.pdf">Git Cheat Sheet</a></li>
<li><code>git help &lt;befehl&gt;</code>: Die eingebaute Hilfe ist besser, als man denkt</li>
</ul>
<p>The post <a href="https://creatronix.de/das-grose-git-tutorial/">Das große Git-Tutorial</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Lerne neue Programmiersprachen schneller mit diesen Coding Challenges</title>
		<link>https://creatronix.de/lerne-neue-programmiersprachen-schneller-mit-diesen-coding-challenges/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 22 Mar 2026 07:20:50 +0000</pubDate>
				<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7954</guid>

					<description><![CDATA[<p>Motivation Motivation Das Erlernen einer Programmiersprache kann herausfordernd sein. Es gibt zwar unzählige Artikel und Tutorials, doch echtes Verständnis entsteht vor allem durch regelmäßige Wiederholung und praktische Anwendung. Wer Konzepte immer wieder in kleinen Übungen, Katas und realen Problemen einsetzt, entwickelt mit der Zeit eine Art Muscle Memory fürs Programmieren. Genau diese Routine hilft dabei,&#8230;</p>
<p>The post <a href="https://creatronix.de/lerne-neue-programmiersprachen-schneller-mit-diesen-coding-challenges/">Lerne neue Programmiersprachen schneller mit diesen Coding Challenges</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<h2>Motivation</h2>
<p>Das Erlernen einer Programmiersprache kann herausfordernd sein. Es gibt zwar unzählige Artikel und Tutorials, doch echtes Verständnis entsteht vor allem durch regelmäßige Wiederholung und praktische Anwendung.</p>
<p>Wer Konzepte immer wieder in kleinen Übungen, Katas und realen Problemen einsetzt, entwickelt mit der Zeit eine Art Muscle Memory fürs Programmieren. Genau diese Routine hilft dabei, Syntax, Denkweisen und Lösungsstrategien nachhaltig zu verinnerlichen.</p>
<h2>Die Herausforderungen</h2>
<p>Die Programmieraufgaben sind sprachunabhängig, sodass du jede moderne Sprache verwenden kannst, die das Schreiben von Konsolenanwendungen unterstützt.</p>
<h2>🟢 Level 1 – Grundlagen (Syntax &amp; einfache Logik)</h2>
<ol>
<li>Schreibe das berühmte / berüchtigte „Hello World“</li>
<li>Schreibe ein Skript, das alle Zahlen von 1 bis 365 in die Konsole ausgibt</li>
<li>Schreibe ein Skript, das 10 Zufallszahlen zwischen 1 und 10 ausgibt</li>
<li>Schreibe ein Skript, das alle Buchstaben des Alphabets (großgeschrieben) mit ihrer jeweiligen Position ausgibt, z. B. 1: A, 2: B</li>
<li>Schreibe deinen ersten Unit-Test für eine Funktion <code>is_even(num)</code>, die <code>true</code> zurückgibt, wenn die Zahl gerade ist</li>
</ol>
<h2>🟡 Level 2 – Einfache Funktionen &amp; Kontrolle</h2>
<ol>
<li>Schreibe eine Funktion <code>to_upper</code>, die einen String von lower_case nach upper_case umwandelt</li>
<li>Die Funktion <code>compare(num1, num2)</code> soll
<ol>
<li>-1 zurückgeben, wenn <code>num1</code> kleiner als <code>num2</code> ist</li>
<li>ansonsten 1 zurückgeben</li>
<li>wenn beide Werte gleich sind, 0 zurückgeben</li>
</ol>
</li>
<li>Die Funktion <code>simple_sum(num)</code> soll alle Zahlen von 1 bis <code>num</code> aufsummieren
<ol>
<li>Beispiel: Bei Eingabe 4 soll das Ergebnis 10 sein</li>
<li>Für Testfälle liegt <code>num</code> zwischen 1 und 1000</li>
</ol>
</li>
<li>Die Funktion <code>time_convert(minutes)</code> soll Minuten in Stunden und Minuten umwandeln (z. B. 63 → 1:03)</li>
<li>Die Funktion <code>first_reverse(input)</code> soll den String umdrehen</li>
</ol>
<h2>🟠 Level 3 – Strings &amp; Arrays</h2>
<ol>
<li>Die Funktion <code>alphabet_soup(input)</code> soll den String alphabetisch sortieren</li>
<li>Die Funktion <code>longest_word(sentence)</code> soll das längste Wort zurückgeben</li>
<li>Die Funktion <code>letter_changes(input)</code> soll Buchstaben ersetzen und Vokale kapitalisieren</li>
</ol>
<h2>🔵 Level 4 – Mathematische Grundlagen</h2>
<ol>
<li>Die Funktion <code>factorial(num)</code> soll die Fakultät berechnen</li>
<li>Schreibe eine Funktion, die Fibonacci-Zahlen erzeugt (inkl. Memoization)</li>
<li>Schreibe eine Funktion, die die Collatz-Sequenz als Liste zurückgibt</li>
<li>Schreibe eine Funktion, die den Mittelwert (Mean) eines Integer-Arrays berechnet</li>
<li>Schreibe eine Funktion, die den Median eines Integer-Arrays berechnet</li>
</ol>
<h2>🟣 Level 5 – Klassische Algorithmen</h2>
<ol>
<li>Schreibe eine Funktion, die ein Integer-Array mit Bubble Sort sortiert</li>
<li>Schreibe eine Funktion, die eine Liste von Primzahlen mithilfe des Siebs des Eratosthenes zurückgibt</li>
<li>Schreibe eine Funktion, die den größten gemeinsamen Teiler mithilfe des euklidischen Algorithmus berechnet</li>
</ol>
<h2>🔴 Level 6 – Anspruchsvoll / Interview-Level</h2>
<ol>
<li>Schreibe eine Funktion, die römische Zahlen in Dezimalzahlen konvertiert</li>
<li>Schreibe eine Funktion, die Dezimalzahlen in römische Zahlen konvertiert</li>
<li>Die Funktion <code>kaprekars_constant(num)</code> berechnet die Anzahl der Schritte bis 6174 erreicht wird</li>
</ol>
<h2>🧪 Hinweis</h2>
<p>Ab der Funktion <code>simple_sum</code> sollte nach dem TDD-Prinzip gearbeitet werden (Test → Implementierung → Refactoring).</p>
<p>The post <a href="https://creatronix.de/lerne-neue-programmiersprachen-schneller-mit-diesen-coding-challenges/">Lerne neue Programmiersprachen schneller mit diesen Coding Challenges</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Was ist Software Engineering? Eine verständliche Einführung</title>
		<link>https://creatronix.de/was-ist-software-engineering-eine-verstaendliche-einfuehrung/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sat, 21 Mar 2026 12:41:56 +0000</pubDate>
				<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7932</guid>

					<description><![CDATA[<p>Software Engineering ist die systematische Entwicklung von Software: von der Idee über die Umsetzung bis zum Betrieb. Programmieren gehört natürlich dazu, ist aber interessanterweise oft nur ein kleiner Teil des Ganzen. Disclaimer Die folgende Unterteilung in Programmierung, Entwicklung und Engineering ist ein Versuch einer Einordnung von Prozessen, Methoden und Tools. Ich habe dieses Modell entwickelt,&#8230;</p>
<p>The post <a href="https://creatronix.de/was-ist-software-engineering-eine-verstaendliche-einfuehrung/">Was ist Software Engineering? Eine verständliche Einführung</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Software Engineering ist die systematische Entwicklung von Software: von der Idee über die Umsetzung bis zum Betrieb. Programmieren gehört natürlich dazu, ist aber interessanterweise oft nur ein kleiner Teil des Ganzen.</p>
<h2>Disclaimer</h2>
<p>Die folgende Unterteilung in Programmierung, Entwicklung und Engineering ist ein Versuch einer Einordnung von Prozessen, Methoden und Tools. Ich habe dieses Modell entwickelt, um unseren Auszubildenden und Praktikanten, die oft keine Vorkenntnisse hatten, Software-Engineering beizubringen.</p>
<p>Daher enthält es einige persönliche Ansichten und möglicherweise keine präzisen Definitionen. Es spiegelt meine fast 20-jährige Erfahrung in der Softwarebranche als Entwickler, Tester, QA-Mitarbeiter und Teamleiter wider.</p>
<h2><img decoding="async" src="https://creatronix.de/wp-content/uploads/2023/01/mental-model.png" alt="" width="391" height="392" class="alignnone size-full wp-image-6606" srcset="https://creatronix.de/wp-content/uploads/2023/01/mental-model.png 391w, https://creatronix.de/wp-content/uploads/2023/01/mental-model-300x300.png 300w, https://creatronix.de/wp-content/uploads/2023/01/mental-model-150x150.png 150w" sizes="(max-width: 391px) 100vw, 391px" /></h2>
<h2>Programmierung: der Kern</h2>
<p>Ein bekannter Spruch lautet:</p>
<blockquote><p>A programmer is an organism that turns coffee and pizza into code.</p></blockquote>
<p>Programmieren bedeutet, Anforderungen des Kunden in ausführbare Anweisungen, die ein Computer versteht, zu übersetzen. Das kann eine einzelne Person — ein Programmierer — tun.</p>
<h3>Programmiersprachen</h3>
<p>Ein Programmierer braucht eine oder mehrere Programmiersprachen um <strong>Quellcode</strong> zu erstellen. Quellcode oder oft nur <strong>Code</strong> ist Text in einer Sprache wie C, <a href="https://creatronix.de/modernes-c-plus-plus/">C++</a>, Java oder <a href="https://creatronix.de/python-tips-tricks-for-junior-developers/">Python</a>. Jede Sprache definiert klare Regeln für Syntax und Semantik.</p>
<h3>Vom Quelltext zum Programm</h3>
<ol>
<li>Quelltext schreiben (Editor oder IDE)</li>
<li>Kompilieren (z. B. C/C++)</li>
<li>Linken und ausführbare Datei erzeugen</li>
</ol>
<p>Beispiel in C:</p>
<div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C"><code>#include &lt;stdio.h&gt;

int main(void) {
    printf("Hello world\n");
    return 0;
}</code></pre>
</div>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>gcc -Wall -g -c hello.c
gcc -o hello hello.o -lm</code></pre>
</div>
<p>&nbsp;</p>
<p><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/compiler_linker-1024x150.png" alt="" width="1024" height="150" class="alignnone size-large wp-image-7929" srcset="https://creatronix.de/wp-content/uploads/2026/03/compiler_linker-1024x150.png 1024w, https://creatronix.de/wp-content/uploads/2026/03/compiler_linker-300x44.png 300w, https://creatronix.de/wp-content/uploads/2026/03/compiler_linker-768x112.png 768w, https://creatronix.de/wp-content/uploads/2026/03/compiler_linker.png 1031w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<p>Das reicht schon, damit wurde bereits ein Programm erstellt. Für echte Projekte oder Produkte reicht das reine<br />
Programmieren aber noch nicht aus.</p>
<h2>Softwareentwicklung: vom Code zum Produkt</h2>
<p>Sobald mehrere Personen beteiligt sind oder Kundennutzen im Fokus steht, kommen Prozesse, Rollen und Werkzeuge hinzu.</p>
<h3>Requirements Tracking &#8211; Anforderungen erfassen und klären</h3>
<p>Damit ein Team von Programmierern das Richtige baut, müssen Anforderungen des Kunden klar beschrieben werden. Eine Anforderung, die in Textform niedergeschrieben wurde, nennt man auch <strong>Requirement</strong>. Für die Formulierung haben sich zwei Formate etabliert:</p>
<ul>
<li>User Story: Als <strong>Rolle</strong> möchte ich <strong>Funktion</strong>, damit <strong>Nutzen</strong>.</li>
<li>Use Case: strukturierte Beschreibung einer Interaktion zwischen Nutzer und System</li>
</ul>
<p>Anforderungen erhalten IDs, Status und Verweise auf Implementierung und Tests. So bleibt über den gesamten Lebenszyklus nachvollziehbar, was umgesetzt, geändert oder verworfen wurde.</p>
<p>Auch die guten alten Lastenhefte (Was der Kunde will) und Pflichtenhefte (Was wir verstanden haben und auch umsetzen werden) haben oft noch ihre Daseinsberechtigung.</p>
<h3>Neue Rollen</h3>
<p>Dedizierte Tester entlasten ein Team von Programmierern und erhöhen die Produktqualität, weil sie Programme systematisch aus Nutzer- und Risikoperspektive prüfen.</p>
<p>Typische Aufgaben für Tester sind:</p>
<ul>
<li>Testfälle aus den Anforderungen ableiten</li>
<li>Teststrategie und Testdaten definieren</li>
<li>Manuelle und automatisierte Tests durchführen</li>
<li>Fehler sauber dokumentieren und priorisieren</li>
<li>Regressionsrisiken vor Releases bewerten</li>
</ul>
<p>Wichtig: Tester &#8220;testen nicht nur am Ende&#8221;, sondern arbeiten <a href="https://creatronix.de/wie-baue-ich-eine-entwicklungsbegleitende-software-qualitatssicherung-auf/">früh</a> mit den Programmierern zusammen. So werden Qualitätsprobleme früher sichtbar und deutlich günstiger behoben.</p>
<h3>Dokumentation</h3>
<p>Gute <strong>Dokumentation</strong> entlastet Teams im Alltag und reduziert Wissensinseln.</p>
<ul>
<li>Produktdokumentation: Was kann das System aus Nutzersicht?</li>
<li>Technische Dokumentation: Architektur, Schnittstellen, Betriebswissen</li>
<li>Entscheidungsdokumentation: Warum wurde etwas so gebaut?</li>
</ul>
<p>Wichtig ist nicht &#8220;möglichst viel Text&#8221;, sondern aktuelle, auffindbare und wartbare Dokumentation.</p>
<h3>Versionsverwaltung nutzen</h3>
<p>Werkzeuge wie <a href="https://creatronix.de/das-grose-git-tutorial/">Git</a> speichern den kompletten zeitlichen Verlauf einer Codebasis. Sie ermöglichen damit:</p>
<ul>
<li>Zusammenarbeit im Team</li>
<li>Nachvollziehbare Änderungen</li>
<li>Rückkehr zu früheren Ständen</li>
</ul>
<p>Hinweis: Git ersetzt kein vollständiges Backup-Konzept.</p>
<h3><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/03/branching-1024x391.png" alt="" width="1024" height="391" class="alignnone wp-image-7931 size-large" srcset="https://creatronix.de/wp-content/uploads/2026/03/branching-1024x391.png 1024w, https://creatronix.de/wp-content/uploads/2026/03/branching-300x115.png 300w, https://creatronix.de/wp-content/uploads/2026/03/branching-768x293.png 768w, https://creatronix.de/wp-content/uploads/2026/03/branching.png 1194w" sizes="(max-width: 1024px) 100vw, 1024px" /></h3>
<h3>Builds automatisieren &amp; Abhängigkeiten verwalten</h3>
<p>Moderne Anwendungen nutzen viele oft externe Bibliotheken. Package Manager wie <code>cargo</code>, <code>npm</code> oder <code>gradle</code> helfen bei einheitlichen Builds und reproduzierbaren Versionen. Ziel: Alle können jederzeit denselben Build erzeugen.</p>
<p>Zusätzlich braucht es klare <strong>Build Tools</strong> und ein belastbares <strong>Build System</strong>:</p>
<ul>
<li><a href="https://creatronix.de/compiler-optionen-fur-sauberes-c/">standardisierte Build-Kommandos</a> lokal und in CI</li>
<li>reproduzierbare Artefakte über Umgebungen hinweg</li>
<li>schnelle, stabile Pipelines mit klarer Fehlerdiagnose</li>
</ul>
<h3>IDE</h3>
<p>Während beim reinen Programmieren ein einfacher Texteditor ausreichen kann, verwenden Softwareentwickler in der Praxis meist leistungsfähige IDEs.</p>
<p>Eine IDE bündelt zentrale Entwicklungsaufgaben in einem Werkzeug:</p>
<ul>
<li>Code schreiben mit Syntaxprüfung und Autovervollständigung</li>
<li>Navigation durch große Codebasen (z. B. &#8220;Gehe zu Definition&#8221;)</li>
<li>Refactoring mit geringem Fehlerrisiko</li>
<li>Debugging mit Breakpoints und Variableninspektion</li>
<li>Direkte Integration von Tests, Linter und Build-Prozessen</li>
<li>Anbindung an Versionsverwaltung wie Git</li>
</ul>
<p>Der eigentliche Nutzen liegt in der Produktivität und Qualität: Teams arbeiten schneller, konsistenter und machen weniger vermeidbare Fehler.</p>
<h3>Issue Tracking &#8211; Arbeit transparent machen</h3>
<p>Issues, Bugs und Aufgaben werden in einem Tracking-System verwaltet (z. B. Jira, YouTrack, GitHub Issues). So bleiben Prioritäten, Zuständigkeiten und Fortschritt nachvollziehbar.</p>
<h3>Projektorganisation mit Scrum oder Kanban</h3>
<p>Damit Teamarbeit planbar und transparent bleibt, wird Arbeit in kleine, priorisierte Einheiten aufgeteilt und sichtbar gemacht.</p>
<p>Bei <strong>Scrum</strong> erfolgt die Planung meist in festen Iterationen (Sprints), z. B. alle ein bis zwei Wochen:</p>
<ul>
<li>Ziele für den Sprint festlegen</li>
<li>Aufgaben gemeinsam schätzen und zuschneiden</li>
<li>Fortschritt täglich abstimmen</li>
<li>Ergebnisse am Sprint-Ende überprüfen und verbessern</li>
</ul>
<p>Bei <strong>Kanban</strong> steht der kontinuierliche Fluss im Vordergrund:</p>
<ul>
<li>Aufgaben visualisieren (z. B. To-do, In Arbeit, Erledigt)</li>
<li>Parallelarbeit mit WIP-Limits begrenzen</li>
<li>Engpässe früh erkennen und aktiv beseitigen</li>
</ul>
<p>Beide Ansätze helfen, Lieferfähigkeit und Qualität im Alltag stabil zu halten.</p>
<h3>Qualität absichern</h3>
<p>Qualität entsteht nicht zufällig, sondern durch disziplinierte Routinen:</p>
<ul>
<li>Tests (Unit, Integration, End-to-End)</li>
<li><a href="https://creatronix.de/wie-tdd-die-welt-rettet-und-deine-nerven-schont/">TDD</a> (Test-Driven Development)</li>
<li>Debugging</li>
<li><a href="https://creatronix.de/logging-in-python-cheat-sheet/">Logging</a></li>
<li>Linting und statische Codeanalyse</li>
<li>Code Reviews</li>
</ul>
<h4>TDD sinnvoll einsetzen</h4>
<p>Bei TDD schreibst du zuerst einen fehlschlagenden Test, implementierst dann den minimal nötigen Code und verbesserst anschließend die Struktur (Red-Green-Refactor).</p>
<p>TDD ist besonders hilfreich bei:</p>
<ul>
<li>Geschäftslogik mit klaren Regeln</li>
<li>APIs und Modulen mit stabilen Schnittstellen</li>
<li>Codebereichen, die häufig geändert werden</li>
</ul>
<p>So entsteht oft besser testbarer, klarer strukturierter Code und Regressionen werden früher erkannt.</p>
<h3>Struktur schaffen mit Design Patterns</h3>
<p>Design Patterns werden benötigt, weil in Softwareprojekten viele Probleme immer wieder auftreten. Statt jedes Mal eine neue, ungeprüfte Lösung zu bauen, nutzt du bewährte Strukturen.</p>
<p>Sie helfen konkret bei:</p>
<ul>
<li>Verständlichkeit: Andere Entwickler erkennen schneller, wie dein Code aufgebaut ist.</li>
<li>Wartbarkeit: Änderungen sind einfacher, weil Verantwortlichkeiten klarer getrennt sind.</li>
<li>Erweiterbarkeit: Neue Features lassen sich oft mit weniger Umbau integrieren.</li>
<li>Teamkommunikation: Begriffe wie Factory, Observer oder Strategy sind eine gemeinsame Sprache.</li>
<li>Risikoreduktion: Patterns sind praxiserprobt und vermeiden typische Architekturfehler.</li>
</ul>
<p>Kurz: Design Patterns machen Code nicht &#8220;magisch besser&#8221;, aber sie machen komplexe Systeme robuster und für Teams beherrschbarer.</p>
<h2>Software-Engineering &#8211; erfolgreich Großprojekte umsetzen</h2>
<p>Sobald mehrere Teams parallel an einem Produkt arbeiten, reicht reine Softwareentwicklung nicht mehr aus. Spätestens bei Teamgrößen von etwa 8 bis 12 Personen (oder mehreren unabhängigen Feature-Teams) steigen Koordinationsaufwand, Integrationsrisiken und Betriebsverantwortung deutlich.</p>
<p>Dann geht es nicht nur um &#8220;Features bauen&#8221;, sondern auch um:</p>
<ul>
<li>einheitliche technische Leitplanken</li>
<li>verlässliche Release- und Betriebsprozesse</li>
<li>klare Verantwortlichkeiten zwischen Entwicklung, Produkt und Betrieb</li>
<li>skalierbare Qualitätssicherung über Teamgrenzen hinweg</li>
</ul>
<p>Genau hier beginnt der eigentliche Mehrwert von Software Engineering.</p>
<h3>Neue Rollen</h3>
<p>Mit wachsender Produkt- und Teamgröße entstehen zusätzliche Rollen, die Entwicklung strukturieren und skalierbar machen.</p>
<p><strong>Projektleiter</strong> koordinieren Zeit, Budget, Abhängigkeiten und Risiken.<br />
Sie sorgen dafür, dass Entscheidungen transparent sind und Teams in die gleiche Richtung arbeiten.</p>
<p><strong>Requirements Engineers</strong> präzisieren Anforderungen und übersetzen fachliche Ziele in umsetzbare Spezifikationen.<br />
Dadurch sinken Missverständnisse zwischen Fachseite, Produktmanagement und Entwicklung.</p>
<p><strong>DevOps-Teams</strong> bauen die Brücke zwischen Entwicklung und Betrieb.<br />
Sie verantworten u. a. CI/CD-Pipelines, Deployment-Prozesse, Monitoring und stabile Betriebsabläufe.</p>
<p>Wichtig ist das Zusammenspiel: Diese Rollen ersetzen nicht die Entwicklung, sondern schaffen den Rahmen, in dem Entwicklung zuverlässig liefern kann.</p>
<h3>Architektur definieren</h3>
<p>Architektur beschreibt die grobe Struktur und die Kommunikationswege eines Systems, z. B.:</p>
<ul>
<li>Frontend &#8211; Backend &#8211; Datenbank</li>
<li>Schichtenarchitektur</li>
<li>Event-basierte Systeme (Pub/Sub)</li>
<li>Dependency-Injection-Frameworks</li>
</ul>
<p>Sie legt die Leitplanken fest, nicht jedes Implementierungsdetail.</p>
<h3>Software betreiben und ausliefern</h3>
<p>Zum Engineering gehört auch der Betrieb:</p>
<ul>
<li>CI/CD (Continuous Integration / Continuous Deployment) für automatisches Bauen, Testen und Ausrollen</li>
<li>Staging-Umgebungen vor Produktion</li>
<li><a href="https://learngitbranching.js.org/?locale=de_DE">Branching-Strategie</a> (z. B. Trunk-Based oder Gitflow)</li>
<li>Containerisierung mit Docker/Kubernetes</li>
<li>Monitoring und Qualitätsmetriken</li>
<li>Release Notes pro Version oder Deployment</li>
<li>Artifact Mirror/Artifact Repository für kontrollierte Abhängigkeiten und Build-Artefakte</li>
</ul>
<h3>Quality Dashboards nutzen</h3>
<p><strong>Quality Dashboards</strong> machen Qualität messbar statt gefühlt. Typische Kennzahlen sind:</p>
<ul>
<li>Testabdeckung und Fehlerraten</li>
<li>Build- und Deployment-Stabilität</li>
<li>Laufzeitmetriken wie Latenz, Fehlerquote und Verfügbarkeit</li>
<li>technische Schulden (z. B. statische Analyse, Duplikate, Komplexität)</li>
</ul>
<p>Nicht jede Metrik passt für jedes Team. Entscheidend ist, wenige Kennzahlen konsequent zu nutzen und Trends zu beobachten.</p>
<h3>Blindspots im Alltag</h3>
<p>Einige Themen fehlen in vielen Teams anfangs, sind aber zentral für professionelles Software Engineering:</p>
<ul>
<li>Security by Design: Threat Modeling, Dependency-Scans, Secret-Management, Sicherheitsupdates</li>
<li>Reliability Engineering: SLOs, Alerting, Runbooks, Incident- und Postmortem-Prozesse</li>
<li>Wartbarkeit: technischer Schuldenabbau, regelmäßige Refactorings, klare Ownership</li>
<li>Wissensverteilung: Onboarding, Pairing, Reviews und Dokumentation statt &#8220;Single Points of Failure&#8221;</li>
</ul>
<h2>Fazit</h2>
<p>Software Engineering ist mehr als Programmieren. Es verbindet Technik, Prozesse und Zusammenarbeit, damit Software langfristig zuverlässig, wartbar und nutzbar bleibt.</p>
<p>Wie ich eingangs erwähnte: Dies ist ein gedankliches Modell. Die Grenzen zwischen den Bereichen sind fließend: Man kann natürlich von Anfang an Versionskontrolle einsetzen und ein CI/CD-System für ein einfaches „Hello World“-Programm einrichten. Mein Hauptanliegen ist es, das Bewusstsein dafür zu schärfen, dass Softwareentwicklung eine Vielzahl von Werkzeugen und Praktiken umfasst, deren Lernkurve steil ist, wenn man versucht, alles auf einmal zu beherrschen. Durch die Unterteilung des Fachgebiets in drei Ebenen lassen sich die Konzepte möglicherweise leichter schrittweise erfassen und die Fähigkeiten von innen nach außen entwickeln.</p>
<h2>Links</h2>
<p><a href="https://creatronix.de/die-junior-und-die-senior-rolle/">Die Junior und die Senior-Rolle</a></p>
<p><a href="https://creatronix.de/wie-baue-ich-eine-entwicklungsbegleitende-software-qualitatssicherung-auf/">Wie baue ich eine entwicklungsbegleitende Software-Qualitätssicherung auf?</a></p>
<p><a href="https://creatronix.de/wie-tdd-die-welt-rettet-und-deine-nerven-schont/">Wie TDD die Welt rettet und deine Nerven schont</a></p>
<p><a href="https://creatronix.de/pytest-tutorial/">Pytest Tutorial</a></p>
<p><a href="https://creatronix.de/so-verwendest-du-google-test-in-deinem-cpp-projekt/">So verwendest du Google Test in deinem C++-Projekt</a></p>
<p><a href="https://creatronix.de/alles-was-du-ueber-scrum-wissen-musst/">Alles was du über Scrum wissen musst</a></p>
<p><a href="https://creatronix.de/writing-as-complementary-skill-for-your-sw-engineering-career/">Writing as a complementary skill for your SW engineering career</a></p>
<h2>Literatur</h2>
<p><a href="https://amzn.to/40E6sBJ">The Software Engineer&#8217;s Guidebook</a></p>
<p><a href="https://frankwestphal.de/ftp/Westphal_Testgetriebene_Entwicklung.pdf">Mein erster Kontakt mit TDD (old but gold) </a></p>
<p>The post <a href="https://creatronix.de/was-ist-software-engineering-eine-verstaendliche-einfuehrung/">Was ist Software Engineering? Eine verständliche Einführung</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>So verwaltest du deine Roboter mit Ansible</title>
		<link>https://creatronix.de/so-verwaltest-du-deine-roboter-mit-ansible/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Wed, 11 Mar 2026 19:43:10 +0000</pubDate>
				<category><![CDATA[Robotics]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7893</guid>

					<description><![CDATA[<p>Motivation Eine einzelne Ubuntu-Maschine zu warten, ist noch überschaubar. Man loggt sich per SSH ein, installiert ein paar Pakete, macht ein Update – und dann läuft die Kiste wieder. In der Robotik bleibt es aber selten bei einer Maschine. Sobald mehrere Roboter im Einsatz sind, sitzt man plötzlich vor einem kleinen Zoo aus Linux-Systemen. Dann&#8230;</p>
<p>The post <a href="https://creatronix.de/so-verwaltest-du-deine-roboter-mit-ansible/">So verwaltest du deine Roboter mit Ansible</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Eine einzelne Ubuntu-Maschine zu warten, ist noch überschaubar. Man loggt sich per SSH ein, installiert ein paar Pakete, macht ein Update – und dann läuft die Kiste wieder.</p>
<p>In der Robotik bleibt es aber selten bei einer Maschine. Sobald mehrere Roboter im Einsatz sind, sitzt man plötzlich vor einem kleinen Zoo aus Linux-Systemen.</p>
<p>Dann beginnt die klassische Runde:<br />
SSH auf Rechner eins, Updates einspielen.<br />
SSH auf Rechner zwei, dieselben Updates einspielen.<br />
SSH auf Rechner drei – na, Du ahnst es schon.</p>
<p>Spätestens nach dem fünften Roboter merkt man: Das ist weniger Systemadministration und mehr Fleißarbeit mit Copy-Paste.</p>
<p>Genau hier kommt Ansible ins Spiel. Mit sogenannten Playbooks beschreibt man einfach den gewünschten Zustand der Systeme – welche Pakete installiert sein sollen, welche Konfigurationen gelten, welche Updates eingespielt werden. Ansible kümmert sich dann darum, diese Zustände automatisch auf allen Zielrechnern umzusetzen.</p>
<p>Gerade in Robotik-Umgebungen mit vielen verteilten Rechnern sorgt dieser Ansatz dafür, dass Wartung nicht mehr Handarbeit ist – sondern planbar, reproduzierbar und vor allem deutlich entspannter.</p>
<h2>Ansible</h2>
<p>Ansible wurde 2012 von Michael DeHaan entwickelt und als Open-Source-Projekt veröffentlicht. 2015 wurde das Unternehmen Ansible, Inc. von Red Hat übernommen, das wiederum seit 2019 zu IBM gehört.</p>
<p>Es ist ein agentenloses Automatisierungstool – das heißt, auf den Zielrechnern muss keine zusätzliche Software installiert werden. Ansible verbindet sich einfach per SSH und führt die gewünschten Aufgaben aus.</p>
<h2>Setup</h2>
<p>Für dieses Tutorial brauchst Du einen Ubuntu-PC und einen Raspberry Pi mit einem installierten Ubuntu. Auf deinem Control-Rechner (also deinem PC) läuft Ansible und der SSH Client, auf dem Raspberry (also dem Remote-Rechner) muss der SSH-Server aktiviert sein.</p>
<h2>Installation</h2>
<p>Auf deinem Control-Rechner installierst du Ansible wie folgt:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo apt update
sudo apt install ansible
sudo apt install sshpass</code></pre>
</div>
<p>Jetzt kannst Du testen, ob die Installation geklappt hat:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ansible --version</code></pre>
</div>
<h2>SSH aktivieren</h2>
<p>Damit Ansible funktioniert, muss auf dem Raspberry aka Remote-Rechner SSH eingerichtet sein.<br />
Probier mal im Terminal deines Control-Rechners aus, dich mit dem Raspberry zu verbinden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ssh pi@192.168.178.50</code></pre>
</div>
<p>Falls das nicht klappt, musst du SSH auf dem Raspberry aktivieren. Das geht ganz einfach über die raspi-config:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo raspi-config</code></pre>
</div>
<p>Dann navigierst du zu &#8220;Interfacing Options&#8221; -&gt; &#8220;SSH&#8221; und aktivierst den SSH-Server.</p>
<h2>Projektordner</h2>
<p>Auf deinem Control-Rechner legst du dir z.B. einen Projektordner an:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>mkdir ~/ansible
cd ansible
touch hosts
touch ansible.cfg
touch update_pi.yml</code></pre>
</div>
<p>Die Ordnerstruktur soll nachher so aussehen:</p>
<p>ansible/<br />
├── hosts<br />
├── update_pi.yml<br />
└── ansible.cfg</p>
<h2>hosts-Datei anlegen</h2>
<p>In der hosts-Datei stehen die Rechner und ihre IP-Adressen bzw. ihre A-Records.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code>[raspberry]
pi1 ansible_host=192.168.178.66 ansible_user=&lt;username&gt;</code></pre>
</div>
<h2>ansible.cfg</h2>
<p>Die ansible.cfg Datei ist die Konfigurationsdatei für Ansible.<br />
Hier kannst du verschiedene Einstellungen vornehmen, z.B. den Pfad zu deiner hosts-Datei.<br />
Ein einfaches Beispiel sieht so aus</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code>[defaults]
inventory = hosts</code></pre>
</div>
<h2>Playbooks</h2>
<p>Playbooks sind die Ansible-Äquivalente zu Skripten, sie beschreiben die gewünschten Zustände der Zielrechner.<br />
Ein einfaches Playbook für die Updates des Raspberrys könnte so aussehen:</p>
<h3>update_pi.yml</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code>---
- name: Update Raspberry Pi
  hosts: raspberry
  become: yes

  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes

    - name: Upgrade all packages
      apt:
        upgrade: dist</code></pre>
</div>
<h3>Im Detail</h3>
<table>
<thead>
<tr>
<th>Ansible</th>
<th>Bash</th>
</tr>
</thead>
<tbody>
<tr>
<td>become: yes</td>
<td>sudo</td>
</tr>
<tr>
<td>apt: update_cache: yes</td>
<td>apt update</td>
</tr>
<tr>
<td>upgrade: dist</td>
<td>apt upgrade</td>
</tr>
<tr>
<td>autoremove: yes</td>
<td>apt autoremove</td>
</tr>
</tbody>
</table>
<h2>Ansible starten</h2>
<p>Wenn du diese drei Dateien anegelegt hast, kann es auch schon losgehen</p>
<h3>ping</h3>
<p>Der ping-Befehl ist ein Testmodul von Ansible, das überprüft, ob der Host erreichbar und ausführbar ist.<br />
Wenn du Passwort-Login benutzt musst du Ansible sagen, dass es nach einem SSH-Passwort fragen soll:<br />
Das -k steht für &#8211;ask-pass</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ansible -i hosts raspberry -m ping -k
SSH password:</code></pre>
</div>
<p>Wenn alles funktioniert, solltest du folgenden Output sehen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pi1 | SUCCESS =&gt; {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}</code></pre>
</div>
<h3>Playbook starten</h3>
<p>Jetzt zum eigentlichen Task:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ansible-playbook -i hosts update_pi.yml -k -K</code></pre>
</div>
<p>Da wir sudu apt update / upgrade machen wollen, müssen wir auch das root-PW übergeben. Das machen wir mit dem Flag -K.<br />
-K steht für &#8211;ask-become-pass, damit wird Ansible nach dem sudo-Passwort fragen.</p>
<h2>Zertifikat-Login</h2>
<p>Da wir aber nicht permanent die<br />
Ansible unterstützt auch die Authentifizierung mit Zertifikaten, was sicherer ist als die Passwort-Authentifizierung.<br />
Dazu musst du auf deinem Control-Rechner ein SSH-Schlüsselpaar generieren und den öffentlichen Schlüssel auf den<br />
Zielrechner kopieren.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ssh-keygen -t rsa -b 4096 -C "@ansible-controller"
ssh-copy-id @192.168.178.66</code></pre>
</div>
<p>Danach kannst du Ansible ohne Passwort verwenden, indem du einfach den Hostnamen angibst:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ansible-playbook -i hosts update_pi.yml -K</code></pre>
</div>
<h2>Weitere Beispiele</h2>
<h3>Ubuntu-Pakete installieren</h3>
<p>Man kann natürlich auch andere Pakete installieren, z.B. git:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code>tasks: 
- name: Install git 
  apt: 
    name: git 
    state: present 
    update_cache: yes</code></pre>
</div>
<h3>Git Repository klonen</h3>
<p>Auch das Klonen eines Git-Repositories ist mit Ansible kein Problem:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-json" data-lang="JSON"><code>tasks: 
- name: Clone Git repo 
    git:
      repo: https://github.com/user/meinprojekt.git 
      dest: /home/pi/meinprojekt 
      version: main</code></pre>
</div>
<h2>Fazit</h2>
<p>Ansible ist ein mächtiges Werkzeug, um die Wartung von Robotern zu automatisieren. Es ermöglicht dir, den Zustand deiner<br />
Systeme zu beschreiben und automatisch umzusetzen, ohne dich manuell auf jedem Rechner einzuloggen. Gerade in Umgebungen<br />
mit vielen verteilten Rechnern spart das enorm viel Zeit und Nerven.</p>
<p>The post <a href="https://creatronix.de/so-verwaltest-du-deine-roboter-mit-ansible/">So verwaltest du deine Roboter mit Ansible</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Alles, was Du über SCRUM wissen musst</title>
		<link>https://creatronix.de/alles-was-du-ueber-scrum-wissen-musst/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Tue, 10 Mar 2026 18:45:41 +0000</pubDate>
				<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7886</guid>

					<description><![CDATA[<p>Motivation SCRUM wurde von Ken Schwaber und Jeff Sutherland entwickelt und ist ein agiles Framework für die Softwareentwicklung. Es hilft Teams, komplexe Projekte zu managen und schnell auf Veränderungen zu reagieren. SCRUM fördert die Zusammenarbeit, Transparenz und kontinuierliche Verbesserung. Werte Commitment, Focus, Openness, Respect, and Courage Vorgehensmodell Interativ &#38; Inkrementell Entwicklungszeitraum wird in Sprints unterteilt&#8230;</p>
<p>The post <a href="https://creatronix.de/alles-was-du-ueber-scrum-wissen-musst/">Alles, was Du über SCRUM wissen musst</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>SCRUM wurde von Ken Schwaber und Jeff Sutherland entwickelt und ist ein agiles Framework für die Softwareentwicklung.<br />
Es hilft Teams, komplexe Projekte zu managen und schnell auf Veränderungen zu reagieren.<br />
SCRUM fördert die Zusammenarbeit, Transparenz und kontinuierliche Verbesserung.</p>
<h2>Werte</h2>
<p>Commitment, Focus, Openness, Respect, and Courage</p>
<h2>Vorgehensmodell</h2>
<h3>Interativ &amp; Inkrementell</h3>
<p>Entwicklungszeitraum wird in Sprints unterteilt</p>
<h3>Sprints</h3>
<p>Dauer: 2-4 Wochen<br />
Ziel: funktionierende Software nach jedem Sprint mit neuen Features die den Geschäftswert des Produkte maximieren</p>
<h3>Messen der Velocity</h3>
<ul>
<li>Velocity = Anzahl der Story Points, die in einem Sprint abgeschlossen wurden</li>
<li>hilft bei der Planung zukünftiger Sprints</li>
</ul>
<h2>Rollen</h2>
<h3>Product Owner</h3>
<p>Stellvertreter des Kunden und der Stakeholder<br />
Der Product Owner ist verantwortlich für:</p>
<ul>
<li>Produktvision und Strategie</li>
<li>Product Backlog erstellen und priorisieren</li>
<li>Anforderungen verstehen, übersetzen und priorisieren</li>
<li>Wert für das Produkt maximieren</li>
<li>Stakeholder koordinieren</li>
</ul>
<p>Er ist die zentrale Entscheidungsinstanz für das Produkt.</p>
<h3>Scrum Master</h3>
<ul>
<li>coacht Teammitglieder und Organisation</li>
<li>verwaltet impediment backlog</li>
<li>löst impediments auf</li>
<li>moderiert Meetings mit dem Ziel, die Effizienz des Teams zu verbessern</li>
<li>schützt das Team vor äußeren Störungen</li>
<li>fördert die Einhaltung von Scrum-Prinzipien und -Praktiken</li>
</ul>
<h3>Scrum Team</h3>
<ul>
<li>schätzt User Stories</li>
<li>setzt Stories um</li>
<li>arbeitet selbstorganisiert</li>
<li>cross-funktional (Entwickler, Tester, Designer etc.)</li>
<li>verantwortlich für die Lieferung von Inkrementen am Ende jedes Sprints</li>
</ul>
<h2>Artefakte</h2>
<h3>Inkrement</h3>
<p>Neue Software, die am Ende eines Sprints fertiggestellt und potenziell auslieferbar ist.</p>
<h3>Product-Backlog</h3>
<ul>
<li>enthält User Stories mit Definition of Done (DoD) und Akzeptanzkriterien</li>
<li>priorisiert nach Business Value</li>
<li>dynamisch, wird während des Projekts angepasst</li>
</ul>
<h3>Sprint-Backlog</h3>
<ul>
<li>alle Items für den Sprint, inkl. DoD und Akzeptanzkriterien</li>
<li>Burndown / Burnup Chart für Fortschrittsverfolgung</li>
</ul>
<h3>Impediment-Backlog</h3>
<p>Für Hindernisse, die das Team daran hindern, die Sprint-Ziele zu erreichen<br />
Beispiele:</p>
<ul>
<li>CI Pipeline funktioniert nicht</li>
<li>Zugang zu Testdaten fehlt</li>
<li>API Dokumentation unvollständig</li>
<li>Fehlende Hardware für Tests</li>
</ul>
<h2>Termine</h2>
<h3>Backlog Refinement (früher Backlog Grooming)</h3>
<p>Zeitpunkt: 1-2 mal pro Sprint, oft in der Mitte des Sprints<br />
Dauer: 1-2 Stunden<br />
Ziel: User Stories mit DoD, Akzeptanzkriterien und Story Points versehen, damit sie für die Sprintplanung bereit sind</p>
<p><strong>Planning Poker</strong></p>
<p>Wie geschätzt wird, lässt Scrum offen, aber Planning Poker ist beliebt.<br />
Jeder Teilnehmer erhält Karten mit Zahlen (z.B. Fibonacci-Folge: 1, 2, 3, 5, 8, 13)</p>
<p>Die Zahlen stehen für die Komplexität der Aufgabe von 1 &#8211; sehr simpel bis 13 sehr komplex.<br />
Der Product Owner liest eine User Story vor, und die Teilnehmer schätzen gleichzeitig, indem sie eine Karte mit ihrer Schätzung hochhalten<br />
Nach der Schätzung diskutieren die Teilnehmer, um ein gemeinsames Verständnis zu erreichen.</p>
<h3>Sprint Planning</h3>
<p>Zeitpunkt: Am Anfang eines Sprints<br />
Dauer: 4-8 Stunden (je nach Sprintlänge)<br />
Ziel: Sprint-Ziele festlegen, User Stories auswählen, die im Sprint bearbeitet werden sollen, und Aufgaben planen</p>
<h3>Daily Standup</h3>
<p>Zeitpunkt: Täglich, meist morgens<br />
Dauer: 15 Minuten<br />
Ziel: Mini-Retro: Awareness für erledigte und aktuelle Tätigkeiten, Impediments an Scrum Master kommunizieren</p>
<h3>Sprint Retro</h3>
<p>Zeitpunkt: Am Sprint-Ende<br />
Dauer: 1-2 Stunden<br />
Ziel: Reflexion über den vergangenen Sprint, Identifikation von Verbesserungsmöglichkeiten, Maßnahmen für den nächsten Sprint planen</p>
<p>&nbsp;</p>
<h2>Scrum but &#8211; Antipatterns</h2>
<p>Wenn Scrum nicht richtig umgesetzt wird, können verschiedene Probleme auftreten, z.B.:</p>
<ul>
<li>Scrum Master ist nur ein Titel, aber keine echte Rolle im Team</li>
<li>Product Owner ist nicht verfügbar oder hat keine Entscheidungsbefugnis</li>
<li>Team arbeitet nicht selbstorganisiert, sondern wird von außen gesteuert</li>
<li>Sprints werden nicht eingehalten, sondern ständig verlängert oder verkürzt</li>
<li>Meetings werden nicht effektiv genutzt, sondern sind reine Zeitverschwendung</li>
<li>Keine klare Definition of Done, was zu unklaren Anforderungen und Qualitätsproblemen führt</li>
<li>Keine regelmäßige Retrospektive, was zu fehlender kontinuierlicher Verbesserung führt</li>
<li>Keine klare Priorisierung im Product Backlog, was zu ineffizienter Arbeit und fehlendem Fokus führt</li>
</ul>
<h2>Quellen</h2>
<p><a href="https://scrumguides.org/scrum-guide.html">https://scrumguides.org/scrum-guide.html</a></p>
<p>The post <a href="https://creatronix.de/alles-was-du-ueber-scrum-wissen-musst/">Alles, was Du über SCRUM wissen musst</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Linux Shell Kommandos Cheatsheet</title>
		<link>https://creatronix.de/linux-shell-kommandos-cheatsheet/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Wed, 04 Mar 2026 11:54:04 +0000</pubDate>
				<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7878</guid>

					<description><![CDATA[<p>Motivation In Robotik-Projekten wird in den meisten Fällen mit einer Linux-Distribution wie Ubuntu gearbeitet, deswegen ist es von Vorteil, sich auch auf der Linux-Konsole aka shell auszukennen. Die Standard-Shell ist meistens Bash (Bourne Again Shell). Viele ROS-Tools erwarten explizit Bash: source /opt/ros/humble/setup.bash Informationen über Kommandos Mit dem Kommando man kann man sich Infos zu den&#8230;</p>
<p>The post <a href="https://creatronix.de/linux-shell-kommandos-cheatsheet/">Linux Shell Kommandos Cheatsheet</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>In Robotik-Projekten wird in den meisten Fällen mit einer Linux-Distribution wie Ubuntu gearbeitet, deswegen ist es von Vorteil, sich auch auf der Linux-Konsole aka shell auszukennen.</p>
<p>Die Standard-Shell ist meistens Bash (Bourne Again Shell). Viele ROS-Tools erwarten explizit Bash:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>source /opt/ros/humble/setup.bash</code></pre>
</div>
<h2>Informationen über Kommandos</h2>
<p>Mit dem Kommando man kann man sich Infos zu den Kommandos geben lassen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash">man ls</pre>
</div>
<p>Eine moderne Alternative ist tldr:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>tldr ls</code></pre>
</div>
<p>Du kannst es unter Ubuntu mit</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo snap install tldr</code></pre>
</div>
<p>installieren.</p>
<h2>Datei-Handling</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
<th>Nützliche Optionen</th>
</tr>
</thead>
<tbody>
<tr>
<td>ls</td>
<td>Verzeichnisinhalt anzeigen</td>
<td>-a verstecdkte Dateien<br />
-h human readable<br />
-l detaillierte List</td>
</tr>
<tr>
<td>cd</td>
<td>Verzeichnis wechseln</td>
<td>.. eine Ebene höher / ~ home Verzeichnis</td>
</tr>
<tr>
<td>pwd</td>
<td>aktuelles Verzeichnis anzeigen</td>
<td></td>
</tr>
<tr>
<td>mkdir</td>
<td>make directory: Verzeichnis erstellen</td>
<td></td>
</tr>
<tr>
<td>touch</td>
<td>Datei erstellen / Timestamp ändern</td>
<td></td>
</tr>
<tr>
<td>rm</td>
<td>Datei / Ordner löschen</td>
<td>-r rekursiv / -f force</td>
</tr>
<tr>
<td>cp</td>
<td>Datei kopieren</td>
<td>-r rekursiv</td>
</tr>
<tr>
<td>mv</td>
<td>Datei verschieben oder umbenennen</td>
<td></td>
</tr>
<tr>
<td>ln</td>
<td>Link erstellen</td>
<td>-s symbolischer Link</td>
</tr>
<tr>
<td>du</td>
<td>Speicherverbrauch anzeigen</td>
<td>-h human readable</td>
</tr>
<tr>
<td>df</td>
<td>freien Speicher anzeigen</td>
<td>-h human readable</td>
</tr>
<tr>
<td>which</td>
<td>Pfad eines Programms anzeigen</td>
<td>-a alle Treffer</td>
</tr>
<tr>
<td>tar</td>
<td>Archive packen/entpacken</td>
<td>-xvf entpacken</td>
</tr>
<tr>
<td>find</td>
<td>Dateien suchen</td>
<td>-name, -type</td>
</tr>
<tr>
<td>grep</td>
<td>Text in Dateien suchen</td>
<td>-r rekursiv</td>
</tr>
</tbody>
</table>
<h2>Benutzer &amp; Rechte</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
<th>Nützliche Optionen</th>
</tr>
</thead>
<tbody>
<tr>
<td>whoami</td>
<td>aktuellen Benutzer anzeigen</td>
<td></td>
</tr>
<tr>
<td>id</td>
<td>Benutzer- und Gruppeninformationen</td>
<td></td>
</tr>
<tr>
<td>sudo</td>
<td>Befehl als root ausführen</td>
<td></td>
</tr>
<tr>
<td>chmod</td>
<td>Dateirechte ändern</td>
<td>chmod +x script.sh</td>
</tr>
<tr>
<td>chown</td>
<td>Eigentümer ändern</td>
<td>sudo chown user:file</td>
</tr>
</tbody>
</table>
<h2>Linux-Pakete &amp; Versionsinformationen</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
<th>Nützliche Optionen</th>
</tr>
</thead>
<tbody>
<tr>
<td>apt</td>
<td>Paketmanager</td>
<td>install <package_name>, update, upgrade</package_name></td>
</tr>
<tr>
<td>dpkg</td>
<td>lokale .deb installieren</td>
<td>dpkg -i file.deb</td>
</tr>
<tr>
<td>lsb_release -a</td>
<td>Distribution anzeigen</td>
<td></td>
</tr>
<tr>
<td>uname -a</td>
<td>Kernelinformationen</td>
<td></td>
</tr>
</tbody>
</table>
<h2>Prozesse</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
<th>Nützliche Optionen</th>
</tr>
</thead>
<tbody>
<tr>
<td>ps</td>
<td>Prozesse anzeigen</td>
<td>ps aux</td>
</tr>
<tr>
<td>top</td>
<td>Systemmonitor</td>
<td></td>
</tr>
<tr>
<td>htop</td>
<td>CPU und RAM Verbrauch anzeigen</td>
<td></td>
</tr>
<tr>
<td>kill</td>
<td>Prozess per PID beenden</td>
<td></td>
</tr>
<tr>
<td>pkill</td>
<td>Prozess per Name beenden</td>
<td></td>
</tr>
<tr>
<td>jobs</td>
<td>Hintergrundjobs anzeigenn</td>
<td></td>
</tr>
</tbody>
</table>
<h2>Netzwerke</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
<th>Nützliche Optionen</th>
</tr>
</thead>
<tbody>
<tr>
<td>ip a</td>
<td>Netzwerkschnittstellen anzeigen</td>
<td></td>
</tr>
<tr>
<td>ping</td>
<td>Verbindung testen</td>
<td>ping heise.de</td>
</tr>
<tr>
<td>ss</td>
<td>offene Ports anzeigen</td>
<td>-tulpen</td>
</tr>
<tr>
<td>curl</td>
<td>HTTP Requests</td>
<td></td>
</tr>
<tr>
<td>ssh</td>
<td>Remote Login</td>
<td></td>
</tr>
</tbody>
</table>
<h2>USB</h2>
<table>
<thead>
<tr>
<th>Befehl</th>
<th>Bedeutung</th>
</tr>
</thead>
<tbody>
<tr>
<td>lsusb</td>
<td>USB-Geräte anzeigen</td>
</tr>
<tr>
<td>dmesg</td>
<td>Kernel-Logs (z. B. beim Einstecken)</td>
</tr>
</tbody>
</table>
<p>The post <a href="https://creatronix.de/linux-shell-kommandos-cheatsheet/">Linux Shell Kommandos Cheatsheet</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Die Junior und die Senior-Rolle</title>
		<link>https://creatronix.de/die-junior-und-die-senior-rolle/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 01 Mar 2026 06:51:46 +0000</pubDate>
				<category><![CDATA[Business & Management]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7865</guid>

					<description><![CDATA[<p>Motivation Als Führungskraft erlebt man immer wieder Spannungen im Team, weil die Erwartungen an eine Rolle oder Position nicht klar definiert sind. Was genau wird von einem Junior erwartet? Woran misst sich eine Senior-Rolle wirklich? Wenn diese Erwartungen nicht transparent sind, entstehen Missverständnisse &#8211; sowohl in der Zusammenarbeit als auch in der persönlichen Weiterentwicklung. Dieser&#8230;</p>
<p>The post <a href="https://creatronix.de/die-junior-und-die-senior-rolle/">Die Junior und die Senior-Rolle</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Als Führungskraft erlebt man immer wieder Spannungen im Team, weil die Erwartungen an eine Rolle oder Position nicht klar definiert sind. Was genau wird von einem Junior erwartet? Woran misst sich eine Senior-Rolle wirklich?</p>
<p>Wenn diese Erwartungen nicht transparent sind, entstehen Missverständnisse &#8211; sowohl in der Zusammenarbeit als auch in der persönlichen Weiterentwicklung. Dieser Text soll helfen, die Unterschiede klarer zu machen und Orientierung zu geben.</p>
<h2>Disclaimer</h2>
<p>Die folgenden Gedanken stammen aus meiner persönlichen Erfahrung in der Softwareentwicklung.<br />
Viele Punkte lassen sich sicher auf andere Disziplinen übertragen, der konkrete Kontext ist jedoch die Arbeit in<br />
Softwareprojekten &#8211; mit Code, Ticketsystemen, Deployments und technischen Abhängigkeiten.</p>
<h2>Junior</h2>
<p>Ehrlich gesagt bin ich kein Fan der Bezeichnung „Junior“. In vielen Betrieben wird dieser Begriff jedoch genutzt, um eine Entry-Level-Rolle zu beschreiben. Dabei geht es weniger um Alter oder gesamte Berufserfahrung, sondern vielmehr um den Fit der Skills zur konkreten Stelle.</p>
<p>Denn egal, wie viel Vorerfahrung jemand aus einer anderen Software-Engineering-Position mitbringt: Jede neue Stelle bietet genügend Herausforderungen, um sich über Wochen oder sogar Monate einarbeiten zu müssen.</p>
<p>Beispiele:</p>
<ul>
<li>Du hast Erfahrung in Vue 3 &#8211; die Firma arbeitet noch mit Vue 2 oder React</li>
<li>Du kennst dich mit CMake aus &#8211; das Unternehmen nutzt jedoch Perforce Jam oder natives make.</li>
</ul>
<p>Je schneller ein Mitarbeiter oder eine Mitarbeiterin den Anforderungen der neuen Rolle gerecht wird und eigenverantwortlich im Tagesgeschäft arbeiten kann, desto eher kann das Attribut „Junior“ abgelegt werden.</p>
<p>Welche Tipps ergeben sich daraus für eine Junior-Rolle?</p>
<h3>Kommunikation &amp; Netzwerken</h3>
<p>Vermeide es, in deiner Junior-Zeit zum Einzelkämpfer zu werden &#8211; Teamwork makes the dream work.</p>
<p><strong>Hilfe suchen &#8211; 30-Minuten-Regel</strong></p>
<p>Wenn du nach 30 Minuten konzentrierter Recherche keinen Ansatz oder keine Richtung siehst &#8211; frag nach Hilfe.</p>
<p>Hast du zwar einen Ansatz und vielleicht schon ersten Code geschrieben, siehst aber nach zwei bis vier Stunden noch kein Licht am Ende des Tunnels, dann solltest du ebenfalls Unterstützung einholen.</p>
<p><strong>Adressatenkreis beachten</strong></p>
<p>Wähle die richtigen Verteiler / Personenkreis. Wer benötigt diese Information wirklich?</p>
<p><strong>Flughöhe beachten (Detailgrad der Information)</strong></p>
<p>Wenn du den passenden Verteiler identifiziert hast, überlege dir, wie viele Details die Empfänger benötigen. Führungskräfte möchten meist das große Ganze, neudeutsch: Big Picture. Techniker freuen sich auch über Code-Snippets oder technische Details.</p>
<p><strong>Medienbrüche vermeiden</strong></p>
<p>Kommt eine Anfrage per E-Mail, antworte nicht im Chat. Wird ein Thema in einem Ticket eröffnet, führe die Diskussion dort weiter. Wenn ihr aneinander vorbeiredet, greift zum Hörer und klärt Unklarheiten synchron.</p>
<p>Wichtig: Fasse das Ergebnis eines Gesprächs anschließend schriftlich zusammen.</p>
<p><strong>Tasks gliedern &#8211; </strong><strong>Nächste sinnvolle Schritte erarbeiten und dokumentieren</strong></p>
<p>Als Full-Stack-Developer in einem Webprojekt solltest du ein Feature sauber zerlegen können, zum Beispiel:</p>
<ul>
<li>Button im Frontend einbauen</li>
<li>API-Endpoint im Backend hinzufügen</li>
<li>Datenbankschema anpassen</li>
</ul>
<p>Diese Schritte sollten auch im Ticket dokumentiert werden.</p>
<p><strong>Feedback &#8211; Frühzeitiges Einbeziehen weiterer Kollegen</strong></p>
<p>Wenn du Schwierigkeiten bei der Zerlegung von Aufgaben hast, frage erfahrene Kollegen, welche Schritte erforderlich<br />
sind.</p>
<p>Auch den Einsatz externer Libraries oder Tools solltest du vorab abstimmen, bevor du tagelang implementierst. Manche<br />
Projekte verbieten bestimmte Technologien, etwa Exceptions oder Introspection/Reflection/RTTI. Auch OSS-Lizenzen wie<br />
GPLv3 oder AGPL können problematisch sein.</p>
<h3>Basiswissen über Produkte und Projekte deiner Firma aneignen</h3>
<p>Versuche, möglichst viel über die Produkte und Projekte deiner Firma zu lernen. Gibt es Ausstellungen, Demoräume oder Hausmessen? Nutze diese Gelegenheiten und beschäftige dich intensiv mit den Produkten. Benutze Produkte aus der Perspektive der Endanwender.</p>
<h3>Code schreiben</h3>
<p>Am Anfang ist es oft schwierig, sich in einer neuen Codebasis zurechtzufinden.</p>
<p>Vermeide es, stundenlang nur Code zu lesen. Starte stattdessen &#8211; falls vorhanden &#8211; einen Unit- oder Komponententest und debugge dich durch die Anwendung. Das ist meist effizienter.</p>
<p>Wenn du grob verstanden hast, was der Code macht, beginne mit kleinen Experimenten. In der Regel steht der Code unter Versionsverwaltung &#8211; du kannst also Änderungen vornehmen und sie jederzeit zurückrollen.</p>
<p>Gibt es noch keine Tests, ist das deine Chance, einen ersten Test für den Happy Path zu schreiben.</p>
<p>Du kannst außerdem:</p>
<ul>
<li>undokumentierte Funktionen mit Docstrings versehen</li>
<li>die Wiki-Seite überarbeiten</li>
<li>Rechtschreibfehler korrigieren oder defekte Links reparieren</li>
</ul>
<p>All das hilft dir, dich mit dem Projekt vertraut zu machen &#8211; und zeigt Proaktivität. „Däumchen drehen“ wird selten<br />
positiv wahrgenommen.</p>
<p><strong>Spekulative Generalisierung vermeiden</strong></p>
<p>„Premature optimization is the root of all evil.“</p>
<p>Nutze beispielsweise die Rule of Three: Implementiere erst zur Generalisierung, wenn du etwas dreimal nahezu identisch implementiert hast. Man sollte nicht zu früh abstrahieren, sondern erst dann, wenn sich ein Muster wirklich bestätigt hat.</p>
<p>Löse die Probleme von heute &#8211; nicht die von morgen.</p>
<p><strong>Versionsverwaltung konsequent benutzen</strong></p>
<p>Committe mehrmals am Tag und pushe deine Änderungen spätestens bevor du abends gehst.</p>
<h3>Einsatz von AI</h3>
<p>Nutze AI-Tools gezielt als Lern- und Sparringspartner.</p>
<p>Lass dir bestehenden Code erklären &#8211; insbesondere dann, wenn du dich in einer neuen Codebasis zurechtfinden musst. Du kannst dir außerdem Verbesserungsvorschläge für deinen eigenen Code geben lassen, etwa in Bezug auf Lesbarkeit, Struktur oder mögliche Edge Cases. Wichtig ist jedoch: Vermeide es, große Code-Blöcke generieren zu lassen, die du selbst noch nicht vollständig verstehst.</p>
<h2>Senior</h2>
<p>Folgende Themen sind aus meiner Sicht entscheidend, um eine Senior-Rolle auszufüllen:</p>
<h3>Ownership &amp; Planung</h3>
<p>Ownership bedeutet, ein Thema aktiv zu übernehmen &#8211; so wie ein Hausbesitzer sich eigenverantwortlich um sein Haus<br />
kümmert. Beispiel: Du bringst den Müll raus, ohne dass dich jemand daran erinnern muss.</p>
<p><strong>Proaktives Handeln</strong></p>
<p>Die Fähigkeit, Themen selbstständig zu identifizieren und anzugehen &#8211; ohne explizite Beauftragung.</p>
<p>Beispiel: Du entwickelst an einem Webportal mit nur einem Produktivsystem, während alle lokal entwickeln. Du erkennst, dass ein Staging-System sinnvoll wäre, um vor dem Live-Deployment ausführlicher zu testen und „Works on my machine“-Probleme zu<br />
vermeiden. Also setzt Du ein Staging-System auf.</p>
<p><strong>Den eigenen Standard nicht verhandelbar machen</strong></p>
<p>Arbeitet ihr mit einem Ticketsystem, dann halte dich daran.</p>
<p>Wenn ein Kunde (intern oder extern) dich bittet, einen Bug zu fixen, arbeite nicht einfach „auf Zuruf“. Lass ein Ticket erstellen oder erstelle es selbst im Namen des Auftraggebers.</p>
<p>Kommuniziere gerne per E-Mail, Telefon oder Chat &#8211; aber halte wichtige Informationen, Entscheidungen und Anforderungen<br />
im Ticket oder Wiki fest. Bereite diese Kommunikation so auf, dass Du und andere noch nach ein paar Tagen wisst, was gemeint war.</p>
<p>#werschreibtderbleibt</p>
<h3>Work Breakdown</h3>
<p>Noch stärker als in der Junior-Rolle ist hier die Fähigkeit gefragt, komplexe Arbeitspakete in umsetzbare Unteraufgaben<br />
zu zerlegen. Ich nenne sie gerne Minimum Viable Actions &#8211; Aufgaben, die nicht weiter zerlegbar sind.</p>
<p>Warum ist das wichtig?</p>
<p>Gerade wenn man mehrere Projekte betreut, wird man häufig unterbrochen (Task Switching). Wenn die kleinste bearbeitbare<br />
Einheit nicht klar definiert ist, entstehen Reibungsverluste.</p>
<p>Ich habe oft erlebt, dass Projekte stagnieren, weil eine Zuarbeit fehlt und alle warten &#8211; obwohl parallel andere Aufgaben erledigt werden könnten.</p>
<p>Deshalb:</p>
<ul>
<li>Identifiziere minimal umsetzbare Tasks</li>
<li>Suche nach Dingen, die jetzt erledigt werden können</li>
<li>Beantrage Rechte</li>
<li>Bestelle Server</li>
<li>Bereite Dokumentation vor.</li>
</ul>
<p>Das verkürzt Ticketlaufzeiten erheblich.</p>
<p><strong>Abgeben von realistischen Schätzungen und Deadlines</strong></p>
<p>Eine häufige Aussage ist: „Das schaffe ich in ein bis zwei Tagen.“</p>
<p>Dabei werden externe Abhängigkeiten oft vergessen &#8211; etwa die IT-Abteilung oder Kollegen, die noch Zugriffsrechte<br />
freigeben müssen.</p>
<p>Für den Auftraggeber zählt nicht nur die reine Entwicklungszeit, sondern wann das Ergebnis vorliegt.</p>
<p>Der „Teufel ist ein Eichhörnchen“: Der Kollege, der Rechte freigeben muss, ist krank oder im Urlaub. Oder der Chef will noch eine Powerpoint sehen, bevor er Budgets freigeben kann &#8211; und aus zwei Tagen werden zwei Wochen.</p>
<p>Solche Risiken sollten in der Planung berücksichtigt und transparent kommuniziert werden.</p>
<h3>Kommunikation und Delegation</h3>
<p>In der Senior-Rolle geht es weniger darum, alles selbst zu erledigen &#8211; sondern darum, dass Dinge erledigt werden.</p>
<p><strong>Aufgaben aktiv abgeben oder „Won’t do“ kommunizieren</strong></p>
<p>Andere in die Lage zu versetzen, Aufgaben zu übernehmen, ist essenziell.</p>
<p>Wenn etwas innerhalb der Deadline nicht realistisch umsetzbar ist, ist es fair, das offen zu kommunizieren: „Das werden wir in diesem Zeitraum nicht schaffen.“</p>
<p>Das gibt dem Auftraggeber die Möglichkeit, Alternativen zu prüfen.</p>
<p><strong>Tasks delegierbar aufbereiten &amp; Erwartungen definieren</strong></p>
<p>Wenn du Aufgaben delegieren willst, müssen sie so vorbereitet sein, dass andere problemlos übernehmen können.<br />
Was für dich selbstverständlich ist, ist für andere &#8211; besonders Junior-Developer &#8211; nicht immer klar. Deshalb:</p>
<ul>
<li>Abläufe explizit dokumentieren</li>
<li>Systeminteraktionen beschreiben</li>
<li>Erwartungshaltungen definieren</li>
<li>Idealerweise im Ticket oder Wiki.</li>
</ul>
<p>Finde eine Balance: Genug Information, damit 80 % der Aufgabe umsetzbar sind &#8211; ohne sie faktisch schon selbst erledigt zu haben ( 80/20-Prinzip).</p>
<p><strong>Rechtzeitige Kommunikation &amp; Statusupdates</strong></p>
<p>Für externe Beteiligte muss klar sein:</p>
<ul>
<li>Wer macht was?</li>
<li>Bis wann?</li>
<li>Welche Blocker gibt es?</li>
</ul>
<p>Frühzeitige Statusupdates sind kein Zeichen von Schwäche, sondern von Professionalität.</p>
<p>Oft glauben wir, blockiert zu sein, weil Informationen fehlen. Spiegelt man diese Blockade dem Kunden, führt das häufig zu Klarheit oder besseren Alternativen.</p>
<p>Erfahrene Entwickler lernen zudem: Kunden kommen oft mit einem Lösungsansatz &#8211; nicht mit dem eigentlichen Problem.</p>
<p>Wenn dieser Ansatz ungeeignet ist, ist es professionell zu sagen: „Wir lösen dein Problem &#8211; aber mit einem anderen Weg.“</p>
<h3>Einsatz von AI</h3>
<p>Verwende AI-Tools gerne intensiv &#8211; aber immer als Sparringpartner, nicht als Ersatz für dein Urteilsvermögen. Als Senior liegt dein Mehrwert nicht nur im Schreiben von Code, sondern in Bewertung, Einordnung und Qualitätssicherung.</p>
<p>Beispiele für sinnvollen Einsatz:</p>
<ul>
<li>Du schreibst den Unit-Test &#8211; die AI schlägt eine mögliche Implementierung vor, die du anschließend kritisch reviewst</li>
<li>Du implementierst eine Lösung &#8211; die AI generiert zusätzliche Testcases oder ergänzt die Dokumentation</li>
<li>Du lässt dir alternative Lösungsansätze oder Refactorings vorschlagen und vergleichst sie mit deinem eigenen Ansatz</li>
<li>Du sparst Zeit, indem du dir neue Projekte, Module oder wiederkehrende Strukturen bootstrappen lässt.</li>
</ul>
<p>Wichtig dabei:</p>
<ul>
<li>Behalte die Architekturhoheit</li>
<li>Hinterfrage generierten Code kritisch</li>
<li>Achte auf Randfälle, Sicherheit und Projektkonventionen</li>
<li>Übernimm nur, was du fachlich vertreten kannst.</li>
</ul>
<p>Ein praktischer Tipp: Committe Änderungen nach jedem sinnvollen Prompt. So bleiben Experimente nachvollziehbar, und du kannst jederzeit zu einem stabilen Stand zurückkehren.</p>
<h3>Fazit</h3>
<p>Ein Senior ist oft wie ein Zirkusartist, der mit vielen Bällen &#8211; oder auch brennenden Hamstern &#8211; jongliert. Idealerweise bleiben alle in der Luft und fallen nicht herunter.</p>
<p>Wenn du in einem Thema blockiert bist, solltest du an einem anderen minimalen Task weiterarbeiten können. So entsteht kontinuierlicher Fortschritt &#8211; auch bei Abhängigkeiten.</p>
<p>Drei Bücher, die mir geholfen haben:<br />
<a href="https://amzn.to/4bvcVUv">The Software Engineer&#8217;s Guidebook</a><br />
<a href="https://amzn.to/4jQz2GU">The 7 Habits of Highly Effective People &#8211; Stephen R. Covey</a><br />
<a href="https://amzn.to/407Jxi1">Extreme Ownership &#8211; Jocko Willink </a></p>
<p>(Amazon Affiliate Links)</p>
<h2>Weiterlesen</h2>
<p><a href="https://creatronix.de/five-books-every-junior-developer-should-own/">Five Books every Junior Developer should own</a></p>
<p><a href="https://creatronix.de/writing-as-complementary-skill-for-your-sw-engineering-career/">Writing as a complementary skill for your SW engineering career</a></p>
<p>The post <a href="https://creatronix.de/die-junior-und-die-senior-rolle/">Die Junior und die Senior-Rolle</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Pytest Tutorial</title>
		<link>https://creatronix.de/pytest-tutorial/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Fri, 06 Feb 2026 20:00:23 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7846</guid>

					<description><![CDATA[<p>Motivation Tests sind ein zentraler Bestandteil moderner Entwicklung. Das Framework pytest macht das Schreiben, Organisieren und Ausführen von Tests einfach, flexibel und leistungsfähig. Tests schreiben und ausführen Installation Zuerst installierst du pytest mit: pip install pytest pytest ist kompatibel mit unittest-Tests und erfordert keine Testklassen. Namenskonventionen Damit pytest Tests automatisch findet, müssen Dateien und Funktionen&#8230;</p>
<p>The post <a href="https://creatronix.de/pytest-tutorial/">Pytest Tutorial</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Tests sind ein zentraler Bestandteil moderner Entwicklung. Das Framework pytest macht das Schreiben, Organisieren und Ausführen von Tests einfach, flexibel und leistungsfähig.</p>
<h2>Tests schreiben und ausführen</h2>
<h3>Installation</h3>
<p>Zuerst installierst du pytest mit:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pip install pytest</code></pre>
</div>
<p>pytest ist kompatibel mit unittest-Tests und erfordert keine Testklassen.</p>
<h3>Namenskonventionen</h3>
<p>Damit pytest Tests automatisch findet, müssen Dateien und Funktionen bestimmte Namen haben:</p>
<ul>
<li>Dateinamen haben test im Namen</li>
<li>Funktionsnamen beginnen mit test_</li>
</ul>
<p>Beispiel:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>def test_example():
    x = 5
    assert x == 5</code></pre>
</div>
<p>Mit pytest im Terminal führt pytest alle passenden Tests aus.</p>
<h3>Testauswahl</h3>
<p>Du kannst gezielt Tests ausführen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>pytest test_module.py::test_function
pytest -k "keyword"</code></pre>
</div>
<p>Optionen wie -v (verbose), -x (bei Fehler abbrechen) oder -s (print-Ausgaben anzeigen) sind sehr praktisch.</p>
<p>Um Optionen nicht immer per Hand eingeben zu müssen, können diese auch in einer pytest.ini angegeben werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-plain" data-lang="Plain Text"><code>[pytest]
pythonpath = .
addopts = -x --durations=0 -vv</code></pre>
</div>
<h2>Fortgeschrittene pytest-Techniken</h2>
<h3>Fixtures</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import pytest

@pytest.fixture(scope="function")
def simple_fixture():
    return 42

def test_function(simple_fixture):
    assert simple_fixture == 42</code></pre>
</div>
<h3>Fixture scopes</h3>
<p>pytest-Fixtures haben einen Scope, der bestimmt, wie oft eine Fixture erzeugt und wiederverwendet wird.<br />
Der Standard-Scope ist function, d. h. die Fixture wird für jeden Test neu ausgeführt.</p>
<p>Weitere Scopes sind:</p>
<ul>
<li>class &#8211; einmal pro Testklasse</li>
<li>module &#8211; einmal pro Datei</li>
<li>package &#8211; einmal pro Paket</li>
<li>session &#8211; einmal pro gesamtem Testlauf</li>
</ul>
<p>Größere Scopes verbessern die Performance, bergen aber das Risiko von geteiltem Zustand zwischen Tests.<br />
Daher gilt: so klein wie möglich, so groß wie nötig.</p>
<h3>Setup and teardown</h3>
<p>Mit pytest können wir klassische setup / teardown Methoden mit fixtures nachbauen</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import pytest

def test_setup_and_teardown():
    assert True

@pytest.fixture(autouse=True, scope="function")
def setup_and_teardown():
    print("SetUp")
    # setup code goes here
    yield
    print("TearDown")
    # teardown code goes here</code></pre>
</div>
<h3>Parametrisierung</h3>
<p>Mit Parametrisierung lässt sich derselbe Test mit verschiedenen Daten ausführen. So umgehst du Duplikate:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import pytest

@pytest.mark.parametrize("data, expected", [
    ([1], 1),
    ([1, 2], 1.5),
    ([1, 2, 3], 2),
])
def test_calculate_mean(data, expected_mean):
    mean = calculate_mean(data)
    assert mean == expected_mean

def calculate_mean(data):
    return sum(data) / len(data)</code></pre>
</div>
<p>&nbsp;</p>
<p>Das definiert mehrere Testinstanzen automatisch.</p>
<h3>Marker</h3>
<p>Marker helfen, Gruppen von Tests zu steuern.<br />
Marker eignen sich z. B. zur Gruppierung nach Plattform, Kategorie oder Dauer.</p>
<p>Es gibt drei eingebaute Marker:</p>
<ul>
<li>skip</li>
<li>skipif</li>
<li>xfail</li>
</ul>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import pytest
import sys

@pytest.mark.skip(reason="Feature not yet implemented")
def test_future():
    pass

@pytest.mark.skipif(sys.platform == "win32", reason="Linux only")
def test_linux_only():
    pass

@pytest.mark.xfail(reason="Bug #123")
def test_known_bug():
    pass</code></pre>
</div>
<h3>Eigene Marker</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>import pytest

@pytest.mark.slow
def test_slow():
    pass</code></pre>
</div>
<p>In pytest.ini:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-plain" data-lang="Plain Text"><code>[pytest]
...
markers =
    slow: mark slow tests</code></pre>
</div>
<p>Dann kannst du testen mit:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pytest -m slow</code></pre>
</div>
<p>Oder alle nicht langsamen Tests laufen lassen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pytest -m "not slow"</code></pre>
</div>
<h3>Nahezu gleiche Vergleiche</h3>
<p>Für Fließkommazahlen ist ein exakter Vergleich oft ungeeignet. pytest bietet das approx-Feature:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>assert 2.2 == pytest.approx(2.3, 0.1)</code></pre>
</div>
<p>Erlaubt eine Toleranz statt exakter Übereinstimmung.</p>
<h3>Exceptions testen</h3>
<p>Mit pytest kannst du das Auftreten von Ausnahmen elegant testen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>def test_zero_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0</code></pre>
</div>
<p>Das prüft, ob ein Fehler erwartet korrekt geworfen wird.</p>
<h2>Test-Reporting &amp; Coverage</h2>
<p>Testabdeckung mit pytest-cov</p>
<p>Mit dem Plugin pytest-cov lässt sich messen, wie viel deines Codes getestet wird:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pip install pytest-cov

pytest --cov=my_app 10_app_test</code></pre>
</div>
<p>Ergebnis: Coverage-Statistiken zeigen an, wie viele Zeilen getestet wurden.</p>
<h3>HTML-Reports</h3>
<p>Du kannst mit demselben Plugin HTML-Berichte erzeugen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pytest --cov=my_app --cov-report=html</code></pre>
</div>
<p>Eine visuelle Übersicht über die Abdeckung hilft bei der Analyse.</p>
<h3>Integration mit Werkzeugen</h3>
<p>Coverage-Daten lassen sich in Tools wie SonarQube einbinden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pytest --cov-report=xml:coverage.xml</code></pre>
</div>
<p>Dadurch kannst du Metriken in CI/CD-Pipelines oder Dashboards verwenden.</p>
<h2>Assertions mit Hamcrest (optional, aber mächtig)</h2>
<p>Neben den eingebauten assert-Anweisungen von pytest kann man auch Hamcrest verwenden.<br />
Hamcrest ist eine Matcher-Bibliothek, die Tests lesbarer und ausdrucksstärker machen kann – besonders bei komplexen Datenstrukturen.</p>
<h3>Installation</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>pip install pyhamcrest</code></pre>
</div>
<p>Import in Tests:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from hamcrest import assert_that, equal_to</code></pre>
</div>
<h3>Warum Hamcrest?</h3>
<p>Vergleich:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>def test_hamcrest_assert():
    result = 42
    assert_that(result, equal_to(42))</code></pre>
</div>
<p>Der Vorteil zeigt sich bei komplexeren Assertions:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>def test_hamcrest_start_with():
    name = "Max Mustermann"
    assert_that(name, starts_with("Max"))

def test_hamcrest_has_length():
    items: Sized = ['apple', 'banana', 'cherry']
    assert_that(items, has_length(3))</code></pre>
</div>
<p>Tests lesen sich mehr wie Spezifikationen.</p>
<h3>Listen &amp; Collections</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-python" data-lang="Python"><code>from hamcrest import assert_that, has_items
from collections.abc import Sequence

def test_compare_list_of_items():
    actual_list_of_items: Sequence[str] = ['apple', 'banana', 'cherry']
    assert_that(actual_list_of_items, has_items("apple", "banana"))</code></pre>
</div>
<h2>Fazit</h2>
<p>pytest ist ein einfaches, doch mächtiges Framework zur Testautomatisierung in Python. Es kombiniert:</p>
<ul>
<li>geringe Einstiegshürde – einfache Tests schnell geschrieben</li>
<li>hohe Flexibilität – Marker, Parameter, Coverage</li>
<li>gute Tools-Integration – HTML-Reports oder CI-Coverage</li>
</ul>
<p>Damit eignet es sich sowohl für Einsteiger als auch für professionelle Test-Pipelines.</p>
<h2>Code</h2>
<p><a href="https://github.com/jboegeholz/pytest_tutorial">https://github.com/jboegeholz/pytest_tutorial</a></p>
<p>The post <a href="https://creatronix.de/pytest-tutorial/">Pytest Tutorial</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>So verwendest du die Kinect unter ROS 2</title>
		<link>https://creatronix.de/so-verwendest-du-die-kinect-unter-ros-2/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sat, 31 Jan 2026 19:47:36 +0000</pubDate>
				<category><![CDATA[Robotics]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7834</guid>

					<description><![CDATA[<p>Motivation Microsoft Kinect v1 &#8211; damals für die Xbox 360 erschienen &#8211; ist eine sehr beliebte Kamera mit einem zusätzlichen Infrarot-Tiefensensor. Sie ist in Robotikkreisen sehr beliebt, weil sich durch die Tiefeninformation und die dadurch möglichen Umrechnungen in eine Point Cloud, Greifbewegungen von Roboterarmen automatisieren lassen. Funktionsweise Der IR-Projektor wirft ein bekanntes Punktmuster Das Muster&#8230;</p>
<p>The post <a href="https://creatronix.de/so-verwendest-du-die-kinect-unter-ros-2/">So verwendest du die Kinect unter ROS 2</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Microsoft Kinect v1 &#8211; damals für die Xbox 360 erschienen &#8211; ist eine sehr beliebte Kamera mit einem zusätzlichen Infrarot-Tiefensensor.<br />
Sie ist in Robotikkreisen sehr beliebt, weil sich durch die Tiefeninformation und die dadurch möglichen Umrechnungen in eine Point Cloud, Greifbewegungen von Roboterarmen automatisieren lassen.</p>
<h2>Funktionsweise</h2>
<ul>
<li>Der IR-Projektor wirft ein bekanntes Punktmuster</li>
<li>Das Muster wird auf Objekten verzerrt</li>
<li>Die IR-Kamera sieht diese Verzerrung</li>
<li>Aus der Abweichung vom Referenzmuster wird die Tiefe berechnet</li>
</ul>
<h2>Disclaimer</h2>
<p>Die Kinect benötigt eine externe Stromversorgung und funktioniert nicht ausschließlich über USB.</p>
<p>Ich hatte mit der Verbindung zu einer Ubuntu VM mit UMT und macos kein Glück. Hier kam es permanent zu frame drops. Deswegen bezieht sich dieses Tutorial auf die Einrichtung auf einem Raspberry Pi 4 mit ROS 2 Humble.</p>
<h2>Anschluss am Raspberry</h2>
<p>Ihr solltet die blauen USB 3.0 Ports verwenden.</p>
<h2>Software</h2>
<p>In diesem Tutorial werden wir</p>
<ul>
<li>libfreenect</li>
<li>image_pipeline</li>
<li>kinect_ros2</li>
</ul>
<p>installieren</p>
<h2>libfreenect</h2>
<p>libfreenect ist ein Open Source Treiber für die Kinect, der auf macOS, Windows und Linux läuft.</p>
<h3>Bauen und installieren</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd ~ 
git clone https://github.com/OpenKinect/libfreenect.git 
cd libfreenect 
mkdir build &amp;&amp; cd build 
cmake .. -DBUILD_EXAMPLES=ON 
make 
sudo make install 
sudo ldconfig</code></pre>
</div>
<p>Jetzt könnt ihr mit</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>freenect-camtest</code></pre>
</div>
<p>ausprobieren, ob die Kinect bereits funktioniert. Es sollte &#8220;Received video frame&#8221; als Ausgabe kommen.</p>
<h3>freenect-glview</h3>
<p>freenect-glview ist ein weiteres Tool, um die Kinect zu testen, ihr könnt es mit:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>freenect-glview</code></pre>
</div>
<p>starten</p>
<p><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-7833" srcset="https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-1024x768.jpg 1024w, https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-300x225.jpg 300w, https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-768x576.jpg 768w, https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-1536x1152.jpg 1536w, https://creatronix.de/wp-content/uploads/2026/01/kinect-raspberry-gltest-2048x1536.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<p>Wenn der Befehl nicht gefunden wurde, müsst ihr noch die fehlende Abhängigkeit freeglut3-dev (Free OpenGL Utility Toolkit) installieren</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo apt install freeglut3-dev</code></pre>
</div>
<p>und die build-Schritte von oben wiederholen</p>
<h2>ROS2-Anbindung</h2>
<p>Voraussetzung ist ein funktionierender ROS-2-Workspace (~/ros2_ws) mit gesourcter Umgebung. Falls ihr das noch nicht gemacht habt, könnten euch diese Artikel helfen:<br />
<a href="https://creatronix.de/so-installierst-du-ros-2-auf-dem-raspberry-pi-ball-chaser-mit-ros2/">https://creatronix.de/so-installierst-du-ros-2-auf-dem-raspberry-pi-ball-chaser-mit-ros2/</a><br />
<a href="https://creatronix.de/so-schreibst-du-pakete-und-nodes-in-ros/">https://creatronix.de/so-schreibst-du-pakete-und-nodes-in-ros/</a></p>
<h3>Image Pipeline installieren</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd ~/ros2_ws/src 
git clone https://github.com/ros-perception/image_pipeline 
cd image_pipeline 
git checkout humble 
cd ~/ros2_ws 
colcon build 
source install/setup.bash</code></pre>
</div>
<p>Um zu schauen, ob alles korrekt funktioniert, können wir nun in einem Terminal</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 run image_proc image_proc</code></pre>
</div>
<p>und in einem zweiten Terminal:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 run rqt_image_view rqt_image_view</code></pre>
</div>
<p>ausprobieren.</p>
<p>Wenn ein Live-Bild in rqt_image_view erscheint, funktioniert die Image Pipeline korrekt.</p>
<h3>rosdep initialisieren</h3>
<p>Falls ihr bisher kein rosdep verwendet habt, müsst ihr das einmalig machen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd ~/ros2_ws 
sudo rosdep init 
rosdep update</code></pre>
</div>
<h3>kinect_ros2 installieren</h3>
<p>Obwohl das Paket offiziell nur bis Galactic gepflegt ist, lässt es sich unter Humble aktuell problemlos aus dem Source bauen.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd ~/ros2_ws/src 
git clone https://github.com/fadlio/kinect_ros2/tree/galactic 
cd ~/ros2_ws 
rosdep install --from-paths src --ignore-src -r -y 
colcon build
source install/setup.bash</code></pre>
</div>
<p>Jetzt können die launch files gestartet werden</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 launch kinect_ros2 pointcloud.launch.py</code></pre>
</div>
<p>Der Node kinect_ros2 publiziert jetzt die Topics /depth/image_raw und /depth/camera_info<br />
Ihr könnt das auf der Kommandozeile mit</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 topic list</code></pre>
</div>
<p>überprüfen.</p>
<p>Wir können jetzt auch die Bilder aufzeichnen und via rosbag in einem mcap speichern. Wir prüfen zuerst, ob die mcap-Erweiterung installiert ist:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 bag info --storage-id mcap</code></pre>
</div>
<p>Falls nicht</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo apt install ros-humble-rosbag2-storage-mcap</code></pre>
</div>
<p>Aufnehmen können wir nun mit</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 bag record /camera/depth/points -s mcap</code></pre>
</div>
<p>Da die Datenmenge bei Bilddaten schnell sehr groß werden können, kann man mcap auch komprimiert aufzeichnen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ros2 bag record \
/camera/depth/points \
-s mcap \
--compression-mode file \
--compression-format zstd</code></pre>
</div>
<p>&nbsp;</p>
<p>The post <a href="https://creatronix.de/so-verwendest-du-die-kinect-unter-ros-2/">So verwendest du die Kinect unter ROS 2</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
