Zum Inhalt springen

Fünf Jahre Softwareentwicklung: Die wichtigsten Lektionen

Fünf Jahre Softwareentwicklung verdichtet: Grundlagen vor Framework-Hypes, Vertrauen durch verlässliche Lieferung, Code für die Nächsten, Einfachheit.

4 Min. Lesezeit
Eine Zeitleiste, die den Werdegang einer Softwareentwicklerin vom ersten Commit bis zur Senior-Position zeigt, mit Meilensteinen und Lektionen entlang des Weges

Grundlagen überdauern Frameworks

Jedes Jahr bringt ein neues Framework. Die Ingenieurinnen und Ingenieure, die sich durchsetzen, sind die, die die Muster darunter verstehen. Frameworks kommen und gehen; Datenstrukturen, Algorithmen, Netzwerktechnik und das Denken in Systemarchitekturen bleiben jahrzehntelang relevant.

tstypescript
// The framework changes. The pattern doesn't.
 
// 2020: Express middleware
app.use((req, res, next) => {
  const start = Date.now();
  res.on("finish", () => {
    console.log(`${req.method} ${req.path} - ${Date.now() - start}ms`);
  });
  next();
});
 
// 2023: Next.js middleware
export function middleware(request: NextRequest) {
  const start = Date.now();
  const response = NextResponse.next();
  response.headers.set("X-Response-Time", `${Date.now() - start}ms`);
  return response;
}
 
// 2025: Whatever comes next — still request interception,
// still wrapping the handler, still measuring duration.
// The framework is syntax. The pattern is knowledge.

Code wird öfter gelesen als geschrieben

Cleverer Code beeindruckt niemanden mehr, wenn er sechs Monate später um drei Uhr morgens debuggt werden muss. Für Lesbarkeit zu schreiben ist kein Zeichen von Schwäche, sondern eines von Erfahrung.

tstypescript
// ❌ Clever — what does this do at a glance?
const r = d.filter((x) => x.s === "a" && x.t > Date.now() - 864e5).reduce(
  (a, c) => ({ ...a, [c.c]: (a[c.c] || 0) + c.v }),
  {} as Record<string, number>
);
 
// ✅ Clear — intention is obvious without comments
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
 
const activeTransactions = deposits.filter(
  (deposit) =>
    deposit.status === "active" && deposit.timestamp > oneDayAgo
);
 
const totalsByCategory = activeTransactions.reduce<Record<string, number>>(
  (totals, transaction) => ({
    ...totals,
    [transaction.category]:
      (totals[transaction.category] ?? 0) + transaction.value,
  }),
  {}
);

Klein und häufig ausliefern

Große Pull Requests liegen tagelang im Review, sammeln Merge-Konflikte an und gehen am Ende mit versteckten Fehlern live. Kleine, fokussierte Änderungen werden in Minuten geprüft und lassen sich mit Zuversicht deployen.

tstypescript
// Deployment metrics that tell the story
interface DeliveryMetrics {
  // Small PRs: reviewed faster, fewer bugs
  avgPRSize: { lines: number; reviewTimeHours: number; bugRate: number };
 
  // Deployment frequency: more deploys = smaller blast radius
  deploysPerWeek: number;
 
  // Lead time: commit to production
  leadTimeHours: number;
 
  // Recovery: how fast you fix things when they break
  meanTimeToRecoveryMinutes: number;
}
 
// What I've seen across teams:
const highPerformingTeam: DeliveryMetrics = {
  avgPRSize: { lines: 150, reviewTimeHours: 2, bugRate: 0.02 },
  deploysPerWeek: 25,
  leadTimeHours: 4,
  meanTimeToRecoveryMinutes: 30,
};
 
const strugglingTeam: DeliveryMetrics = {
  avgPRSize: { lines: 2000, reviewTimeHours: 72, bugRate: 0.15 },
  deploysPerWeek: 1,
  leadTimeHours: 336, // 2 weeks
  meanTimeToRecoveryMinutes: 480, // 8 hours
};
 
// The difference is not talent. It's workflow.

Tests sparen Zeit — irgendwann

Tests zu schreiben fühlt sich langsam an, bis ein Test zum ersten Mal eine Regression abfängt, die sonst in Produktion gelandet wäre. Der Ertrag zeigt sich nicht sofort, aber er summiert sich.

tstypescript
// The test that pays for itself
describe("checkout price calculation", () => {
  it("applies percentage discount before tax", () => {
    const result = calculateTotal({
      items: [{ price: 100, quantity: 2 }],
      discount: { type: "percentage", value: 10 },
      taxRate: 0.08,
    });
 
    // Without this test, a refactor swapped tax and discount order.
    // That bug would have overcharged every customer by ~1%.
    // This test caught it in CI, saved a production incident,
    // and justified every minute spent writing it.
    expect(result.subtotal).toBe(200);
    expect(result.discountAmount).toBe(20);
    expect(result.tax).toBe(14.4); // 8% of $180
    expect(result.total).toBe(194.4);
  });
});

Die beste Architektur ist die einfachste, die funktioniert

Over-Engineering ist der häufigste Fehler in der Mitte der Karriere. Ein Monolith verkraftet mehr Traffic, als man denkt. Microservices lösen organisatorische Probleme, keine technischen — jedenfalls nicht, solange die Teamgröße den operativen Mehraufwand nicht rechtfertigt.

tstypescript
// Year 1 thinking: "We need microservices for scalability"
// Year 3 reality: "We have 40 services, 3 engineers, and
//                  no one understands the full system"
 
// ❌ Premature microservices for a small team
// services/user-service/
// services/order-service/
// services/payment-service/
// services/notification-service/
// services/inventory-service/
// + Kubernetes, service mesh, distributed tracing, 5 databases
 
// ✅ Modular monolith — same boundaries, fraction of the complexity
// src/modules/users/
// src/modules/orders/
// src/modules/payments/
// src/modules/notifications/
// src/modules/inventory/
// + One database, one deployment, clear module boundaries
// Extract to services WHEN you have the team and traffic to justify it

Kommunikation skaliert; Code nicht

Die Wirkungsgrenze von reinem Programmieren liegt niedriger, als man denkt. Die Ingenieurinnen und Ingenieure, die Produkte prägen, Architektur beeinflussen und ihre Teams voranbringen, sind die, die gut kommunizieren — in Design-Dokumenten, Code-Reviews, Incident-Retrospektiven und im Gespräch des Alltags.

tstypescript
// A pull request description that accelerates review
interface EffectivePRDescription {
  what: string;      // What changed
  why: string;       // Why this approach
  how: string;       // Key implementation decisions
  testing: string;   // How you verified it works
  risks: string;     // What could go wrong
  rollback: string;  // How to undo if needed
}
 
// vs. the PR description we've all seen:
// Title: "fix stuff"
// Description: ""
// Files changed: 47
 
// The first one gets reviewed in 20 minutes.
// The second one sits for 3 days.

In die Developer Experience investieren

Die Tools, Skripte und Workflows, die man sich selbst baut, zahlen sich täglich aus. Eine Verbesserung von 30 Sekunden im Entwicklungs-Loop spart über ein Jahr gerechnet Stunden.

tstypescript
// Small investments that compound
const developerExperienceWins = [
  {
    investment: "Hot reload configured properly",
    timePerOccurrence: "10 seconds saved",
    frequency: "200 times/day",
    annualSavings: "~110 hours/year",
  },
  {
    investment: "One-command database reset with seed data",
    timePerOccurrence: "5 minutes saved",
    frequency: "3 times/week",
    annualSavings: "~13 hours/year",
  },
  {
    investment: "Pre-commit hooks catching lint/type errors",
    timePerOccurrence: "15 minutes saved (no CI round-trip)",
    frequency: "5 times/week",
    annualSavings: "~65 hours/year",
  },
  {
    investment: "Automated PR template with checklist",
    timePerOccurrence: "3 minutes saved",
    frequency: "10 times/week",
    annualSavings: "~26 hours/year",
  },
];

Die Lektion unter all den Lektionen

Bei Softwareentwicklung geht es nicht darum, perfekten Code zu schreiben. Es geht darum, Probleme für Menschen zu lösen — für Nutzerinnen und Nutzer, Teammitglieder und das eigene zukünftige Ich —, während man Grenzen bei Zeit, Wissen und Komplexität navigiert. Die besten Ingenieurinnen und Ingenieure sind nicht die, die die meisten Technologien kennen. Es sind die, die beständig gute Abwägungen treffen, klar kommunizieren und die Codebasis besser hinterlassen, als sie sie vorgefunden haben.

Fünf Jahre, Hunderte Pull Requests, Dutzende Vorfälle in Produktion — und die wichtigste Fähigkeit war am Ende das Urteilsvermögen: zu wissen, wann man selbst baut, wann man einkauft, wann man vereinfacht und wann man ausliefert. Der Code ist nur das Artefakt. Was zählt, ist das Denken dahinter.

Wilfredo Rujel

Wilfredo Rujel

Full-Stack-Softwareentwickler

Diesen Beitrag teilenX