bg_image
header

Repository

Ein Repository (deutsch: „Ablage“, „Speicher“ oder „Depot“) ist ein zentraler Ort, an dem Daten, Dateien oder Code organisiert, gespeichert und verwaltet werden. Der Begriff wird je nach Kontext etwas unterschiedlich verwendet – hier sind die häufigsten Bedeutungen:


💻 In der Softwareentwicklung (z. B. bei GitHub oder GitLab):

Ein Repository ist ein Verzeichnis, das den Quellcode eines Projekts, Konfigurationsdateien, Dokumentationen und die Versionsgeschichte enthält. Es dient dazu, die Entwicklung von Software zu verfolgen, Änderungen zu speichern und im Team zusammenzuarbeiten.

  • 🔁 Versionierung: Mit Tools wie Git kann man Änderungen rückgängig machen, alte Versionen vergleichen und neue Features in eigenen Branches entwickeln.

  • 🤝 Zusammenarbeit: Entwickler können gemeinsam am Code arbeiten, Pull Requests stellen, Issues anlegen und Code-Reviews durchführen.

  • 🌍 Remote-Repository: Online-Plattformen wie GitHub, GitLab oder Bitbucket hosten Repositories, damit Teams weltweit gemeinsam entwickeln können.

Beispiel:

git clone https://github.com/nutzername/mein-projekt.git

📦 In Paketverwaltungssystemen (z. B. Linux, Python):

Ein Repository ist eine Sammlung von Softwarepaketen, die von einer Paketverwaltung (z. B. apt, yum, pip) verwendet wird, um Programme zu installieren oder zu aktualisieren.

Beispiel:

sudo apt update
sudo apt install firefox

📚 Allgemeiner Begriff:

Auch außerhalb der IT kann ein „Repository“ eine Art Datenbank oder Archiv sein – z. B. für wissenschaftliche Publikationen oder digitale Sammlungen.


GitHub Actions

GitHub Actions ist ein Feature von GitHub, mit dem du automatisierte Workflows für deine Softwareprojekte erstellen kannst – direkt im GitHub-Repository.


🛠️ Was kann man mit GitHub Actions machen?

Du kannst CI/CD-Pipelines (Continuous Integration / Continuous Deployment) aufbauen, z. B.:

  • Code automatisch testen (z. B. mit PHPUnit, Jest, Pytest)

  • 🛠️ Code bei jedem Push oder Pull Request builden

  • 🚀 Software automatisch deployen (z. B. auf einen Webserver, in die Cloud, zu DockerHub)

  • 📦 Releases erstellen (z. B. ZIP-Dateien, Versionstags)

  • 🔄 Cronjobs oder geplante Tasks laufen lassen


🧱 Wie funktioniert es?

GitHub Actions basiert auf sogenannten Workflows, die du in einer Datei definierst:

  • Die Datei heißt z. B. .github/workflows/ci.yml

  • Sie ist im YAML-Format

  • Du definierst Events (z. B. push, pull_request) und Jobs (z. B. build, test)

  • Jobs bestehen aus Steps, die Befehle oder Aktionen ausführen

Beispiel: Einfacher CI-Workflow für Node.js

name: CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '20'
      - run: npm install
      - run: npm test

🧩 Was sind "Actions"?

Eine Action ist ein einzelner Schritt, den man in einem Workflow ausführt. Es gibt:

  • Vorgefertigte Actions (z. B. actions/checkout, setup-node, upload-artifact)

  • Eigene Actions (z. B. Shell-Skripte oder Docker-Container)

Du kannst Actions im GitHub Marketplace finden und nutzen.


💡 Warum ist das nützlich?

  • Spart manuelle Arbeit

  • Verbessert Codequalität (durch automatisierte Tests)

  • Macht Deployments reproduzierbar

  • Alles direkt in GitHub – kein externer CI-Dienst nötig (wie Jenkins oder Travis CI)


PHP Data Objects - PDO

PDO steht für PHP Data Objects und ist eine Datenbank-Abstraktionsschicht in PHP. Es handelt sich um eine objektorientierte Schnittstelle, mit der du auf verschiedene Datenbanken zugreifen kannst – z. B. MySQL, PostgreSQL, SQLiteohne den Datenbankspezifischen Code stark ändern zu müssen.

Hauptmerkmale von PDO:

Einheitliche API:
Egal ob MySQL, SQLite oder PostgreSQL – du benutzt denselben Code-Stil.

Prepared Statements:
Sicherer Schutz vor SQL-Injektionen durch gebundene Parameter:

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $userId]);

Transaktionen:
PDO unterstützt Transaktionen (wichtig z. B. bei Bankbuchungen).

Fehlerbehandlung per Exception:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Flexibler Datenbankwechsel:
Möchtest du von MySQL auf PostgreSQL wechseln? Meist nur der DSN-String und Treiber müssen geändert werden.

$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$pass = '';

try {
    $pdo = new PDO($dsn, $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Verbindung erfolgreich!";
} catch (PDOException $e) {
    echo "Verbindung fehlgeschlagen: " . $e->getMessage();
}

Fazit:

PDO ist der empfohlene Weg, um in modernen PHP-Anwendungen mit Datenbanken zu arbeiten – besonders wegen der Sicherheit und Flexibilität.


Join Point

Ein Join Point ist ein Begriff aus der Aspect-Oriented Programming (AOP), also der aspektorientierten Programmierung.

Definition:

Ein Join Point ist eine definierte Stelle im Ablauf eines Programms, an der zusätzlicher Code (ein sogenannter Aspekt) eingefügt werden kann.

Typische Beispiele für Join Points:

  • Aufruf einer Methode

  • Ausführung einer Methode

  • Zugriff auf ein Attribut (lesen oder schreiben)

  • Werfen einer Ausnahme

Kontext:

In AOP wird Programmcode modularisiert, indem Querschnittsfunktionen (wie Logging, Sicherheit, Transaktionsmanagement) aus dem eigentlichen Anwendungscode ausgelagert werden. Diese Funktionen werden dann an bestimmten Punkten im Programmablauf (den Join Points) „eingeschnitten“.

Weitere Begriffe im Zusammenhang:

  • Pointcut: Eine Ausdrucksweise, mit der beschrieben wird, welche Join Points betroffen sind (z. B. „alle Methoden mit dem Namen save*“).

  • Advice: Der Code, der an einem Join Point ausgeführt wird (z. B. „logge diesen Methodenaufruf“).

  • Aspect: Eine Kombination aus Pointcut(s) und Advice(s) – also ein vollständiges Modul, das eine Querschnittsfunktion implementiert.

Beispiel (in Spring AOP):

@Before("execution(* com.example.service.*.*(..))")
public void logBeforeMethod(JoinPoint joinPoint) {
    System.out.println("Aufruf von: " + joinPoint.getSignature().getName());
}

→ Hier wird vor jedem Methodenaufruf in einem bestimmten Package ein Logging-Code ausgeführt – und joinPoint.getSignature() liefert Details zum konkreten Join Point.


Aspect Oriented Programming - AOP

Aspect-Oriented Programming (AOP) ist ein Programmierparadigma, das sich darauf konzentriert, Querschnittsfunktionen (Cross-Cutting Concerns) modular zu kapseln. Es ergänzt objektorientierte oder funktionale Programmierung, indem es Code, der sich durch viele Klassen oder Module zieht, auslagert und separat behandelt.


💡 Ziel:

Probleme wie Logging, Sicherheitsprüfungen, Fehlerbehandlung, Transaktionsmanagement oder Performance-Messungen sind typische Cross-Cutting Concerns. Diese wiederholen sich oft in vielen Klassen und Methoden – AOP ermöglicht es, solchen Code zentral zu schreiben und automatisch an den richtigen Stellen auszuführen.


🔧 Grundbegriffe:

  • Aspect: Ein Modul, das eine Querschnittsfunktion kapselt.

  • Advice: Der eigentliche Code, der ausgeführt wird (z. B. vor, nach oder anstatt einer Methode).

  • Join Point: Ein Punkt im Programmablauf, an dem ein Aspect eingreifen kann (z. B. Methodenaufruf).

  • Pointcut: Eine Definition, welche Join Points betroffen sind (z. B. "alle Methoden in Klasse X").

  • Weaving: Der Prozess, bei dem Aspect-Code mit dem eigentlichen Code „verwoben“ wird – zur Laufzeit, beim Kompilieren oder beim Laden.


🛠 Beispiel (in Java mit Spring AOP):

@Aspect
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeMethod(JoinPoint joinPoint) {
        System.out.println("Methode wird aufgerufen: " + joinPoint.getSignature().getName());
    }
}

Dieser Code führt automatisch Logging aus, bevor jede Methode im com.example.service-Paket ausgeführt wird.


✅ Vorteile:

  • Bessere Modularität

  • Weniger Code-Duplikate

  • Trennung von Fachlogik und Querschnittslogik


❌ Nachteile:

  • Kann die Lesbarkeit erschweren (man sieht nicht sofort, was alles beim Methodenaufruf passiert).

  • Debugging kann komplexer sein.

  • Oft framework-abhängig (z. B. Spring, AspectJ).


Assertion

Assertions (auf Deutsch: Behauptungen oder Zusicherungen) sind Programmierkonstrukte, mit denen du Annahmen über den Zustand deines Programms überprüfst. Eine Assertion prüft, ob eine bestimmte Bedingung wahr ist – wenn nicht, wird typischerweise ein Fehler ausgelöst und das Programm abgebrochen.

Beispiel (in Python):

x = 10
assert x > 0   # läuft problemlos
assert x < 5   # AssertionError, weil x nicht kleiner als 5 ist

Zweck von Assertions:

  • Sie helfen beim Debuggen: Du überprüfst, ob bestimmte Voraussetzungen im Code erfüllt sind.

  • Sie dokumentieren implizite Annahmen: z. B. „An dieser Stelle muss die Liste mindestens ein Element haben.“

  • Sie dienen der Fehlersuche in der Entwicklungsphase – im Produktivcode werden sie oft deaktiviert.

Wichtiger Unterschied zu regulären Fehlerbehandlungen:

Assertions sollen Programmfehler aufdecken, nicht Benutzereingaben oder äußere Einflüsse abfangen. Beispiel:

  • assert age > 0 → falsch, wenn age aus Benutzereingabe stammt.

  • Stattdessen: if age <= 0: raise ValueError("Alter muss positiv sein.")

 


Perl Compatible Regular Expressions - PCRE

Perl Compatible Regular Expressions (PCRE) sind eine Implementierung von regulären Ausdrücken, die sich an der Syntax und Funktionalität der Programmiersprache Perl orientiert. Sie bieten eine sehr mächtige, flexible und erweiterte Syntax, die über einfache reguläre Ausdrücke hinausgeht.

Warum „Perl Compatible“?

Perl war eine der ersten Sprachen, die besonders leistungsstarke reguläre Ausdrücke eingeführt hat. Die PCRE-Bibliothek wurde entwickelt, um diese Funktionen auch in anderen Programmiersprachen und Tools verfügbar zu machen – zum Beispiel in:

  • PHP

  • Python (teilweise, re-Modul ähnelt PCRE)

  • JavaScript (mit leichten Abweichungen)

  • grep-Varianten wie pcregrep

  • Texteditoren wie VS Code, Sublime Text etc.


Wichtige Features von PCRE:

Lookahead & Lookbehind:

  • (?=...) – positive Lookahead

  • (?!...) – negative Lookahead

  • (?<=...) – positive Lookbehind

  • (?<!...) – negative Lookbehind

Nicht-gierige Quantifizierer:

  • *?, +?, ??, {m,n}?

Benannte Gruppen:

  • (?P<name>...) oder (?<name>...)

Unicode-Support:

  • \p{L} für Unicode-Buchstaben usw.

Assertions und Grenzen:

  • \b, \B, \A, \Z, \z

Modifikatoren:

  • (?i) für case-insensitive

  • (?m) für multiline usw.

(?<=\buser\s)\w+

Dieser Ausdruck findet Wörter, die nach "user " stehen (Lookbehind).


Fazit:

PCRE sind die "Deluxe-Version" regulärer Ausdrücke – sie sind leistungsfähig, weit verbreitet und flexibel. Wenn du in einem Tool oder einer Sprache arbeitest, die „PCRE unterstützt“, kannst du dich auf die mächtige Perl-ähnliche Syntax freuen.


Guard

In der Softwareentwicklung bezeichnet ein Guard (auch Guard Clause oder Guard Statement) eine Art von Schutzmechanismus innerhalb einer Funktion oder Methode, der sicherstellt, dass bestimmte Bedingungen erfüllt sind, bevor der restliche Code ausgeführt wird.

Einfach erklärt:

Ein Guard ist wie ein Türsteher: Er lässt nur das durch, was erlaubt ist – und alles andere wird frühzeitig beendet.

Typisches Beispiel (in Python):

def divide(a, b):
    if b == 0:
        return "Division durch null nicht erlaubt"  # Guard Clause
    return a / b

In diesem Beispiel schützt der Guard davor, dass eine Division durch null passiert.


Vorteile von Guards:

  • Frühes Beenden bei ungültigen Zuständen

  • Verbesserte Lesbarkeit durch weniger verschachtelte if-else-Strukturen

  • Saubererer Codefluss, da der "Happy Path" (also der normale Ablauf) nicht durch viele Sonderfälle unterbrochen wird


Beispiele in anderen Sprachen:

JavaScript:

function login(user) {
  if (!user) return; // Guard
  // Weiter mit Login-Logik
}

Swift (hat sogar ein eigenes Schlüsselwort guard):

func greet(person: String?) {
  guard let name = person else {
    print("Kein Name übergeben")
    return
  }
  print("Hallo, \(name)!")
}

Impliziter Join

Ein impliziter Join ist eine Art, Tabellen in SQL zu verknüpfen, ohne das Schlüsselwort JOIN explizit zu verwenden. Stattdessen wird der Join über die WHERE-Klausel ausgedrückt.

Beispiel für einen impliziten Join:

SELECT *
FROM kunden, bestellungen
WHERE kunden.kunden_id = bestellungen.kunden_id;

In diesem Beispiel werden die Tabellen kunden und bestellungen durch die Bedingung in der WHERE-Klausel miteinander verknüpft.


Im Vergleich dazu ein expliziter Join:

SELECT *
FROM kunden
JOIN bestellungen ON kunden.kunden_id = bestellungen.kunden_id;

Unterschiede:

Kriterium Impliziter Join Expliziter Join
Syntax Tabellen durch Komma getrennt, Verknüpfung in WHERE Nutzung von JOIN und ON
Lesbarkeit Weniger übersichtlich bei vielen Joins Bessere Struktur und Lesbarkeit
Fehleranfälligkeit Höher (z. B. versehentliches Kreuzprodukt) Weniger, da Join-Bedingungen klarer
ANSI-92-Standard Nicht konform Konform

Wann wird ein impliziter Join verwendet?

Früher war das der Standard, aber heute wird der explizite Join empfohlen, da er lesbarer, strukturierter und weniger fehleranfällig ist – besonders bei komplexen Abfragen mit mehreren Tabellen.


Early Exit

Ein Early Exit bezeichnet in der Programmierung eine Technik, bei der eine Funktion oder ein Algorithmus vorzeitig beendet wird, sobald eine bestimmte Bedingung erfüllt ist. Das Ziel ist meist eine effizientere oder lesbarere Code-Struktur.

Beispiel in einer Funktion:

function getDiscount($age) {
    if ($age < 18) {
        return 10; // 10% Rabatt für Minderjährige
    }
    if ($age > 65) {
        return 15; // 15% Rabatt für Senioren
    }
    return 0; // Kein Rabatt für andere Altersgruppen
}

Hier sorgt der Early Exit dafür, dass die Funktion direkt einen Wert zurückgibt, sobald eine Bedingung zutrifft. Das verhindert überflüssige else-Blöcke und macht den Code übersichtlicher.

Vergleich mit einer verschachtelten Variante:

function getDiscount($age) {
    $discount = 0;
    if ($age < 18) {
        $discount = 10;
    } else {
        if ($age > 65) {
            $discount = 15;
        }
    }
    return $discount;
}

Hier wird die Logik unnötig verschachtelt, was die Lesbarkeit verschlechtert.

Weitere Anwendungsfälle:

  • Fehlertests am Anfang einer Funktion (return oder throw bei ungültigen Eingaben)

  • Schleifen schneller abbrechen, wenn das gewünschte Ergebnis gefunden wurde (break oder return)

Ein Early Exit verbessert also Lesbarkeit, Wartbarkeit und Performance eines Codes.