So vermeiden Sie die Tücken der statischen Analyse


17

Ich arbeite in einer Firma, die Joel Test mit 11 Punkten bewertet - zumindest auf dem Papier.

In der Praxis funktioniert jedoch nichts so gut wie erwartet, und das Projekt läuft seit einem halben Jahr auf DEFCON 1 . Jetzt freuen sich die meisten meiner Kollegen, wenn sie um 18 Uhr nach Hause gehen können - am Sonntag.

Eine der anscheinend guten Methoden, die ich als nicht funktionierend empfand, ist die Verwendung von statischen Analysewerkzeugen. Das Projekt verfolgt sowohl gcc -Wall-Warnungen als auch ein proprietäres und sehr teures "C / C ++" - Tool.

Gcc-Warnungen weisen häufig auf echte (wenn auch meistens harmlose) Fehler hin.

Die proprietären Tools listen jedoch Dinge wie implizite Casts und die Größe eines String-Literal auf. Implizite Casts werden ebenfalls in ihr Stylebook aufgenommen.

Die übliche Praxis ist, dass die Leute dazu gedrängt werden, jede einzelne Warnung zum Schweigen zu bringen. Beachten Sie, dass dies Warnungen ausschließt, bei denen es sich überwiegend um Fehlalarme handelt. Dies ist nicht das Problem.

Das Ergebnis ist:

  1. Die Leute fügen jedem R-Wert und jedem Argument einen Typ-Cast hinzu und verbergen dabei echte, problematische Typenkonflikte.
  2. Die Leute melden sich mit einem Fehler oder verwenden ein anderes problematisches Sprachmerkmal (strlen statt sizeof, strncpy statt strcpy usw.).
  3. Die Warnungen werden stummgeschaltet.
  4. Die Fehlerberichte rollen herein.

Das Wichtigste ist, dass der ursprüngliche Code von Leuten funktioniert und geschrieben wurde, die im Rahmen ihrer Sprachfähigkeiten auf Nummer sicher gingen, während dies bei den Korrekturen nicht der Fall war.

Nun, ich glaube nicht wirklich, dass diese Firma gerettet werden kann. Ich würde jedoch gerne wissen, ob es eine bessere, am besten funktionierende Möglichkeit gibt, die "Pro" -Tools zu verwenden, oder ob ich sie ganz vermeiden sollte, falls ich in Zukunft die Entscheidung treffen sollte.

Eine Lösung, bei der nicht alle Programmierer Genies sind, die nichts falsch machen können. Denn wenn ja, müssen die Werkzeuge nicht unbedingt verwendet werden.


1
Randnotiz: Das GCC hat neben «-Wall» auch die Option «-Wextra» und noch mehr Warnungen, die aus irgendeinem Grund in beiden Metaoptionen nicht enthalten sind. Weitere Informationen finden Sie in den Dokumenten . Im Allgemeinen wird für jede Option angegeben, ob sie durch eine Metaoption aktiviert wurde. Wenn Sie also alle Elemente finden möchten, die nicht aktiviert sind, möchten Sie möglicherweise die Wörter "-Wall" und "-Wextra" in allen Dokumenten markieren und sehen, welche noch nicht verwendet wurden.
Hi-Angel

Ich möchte auch hinzufügen, dass ich mich wundere, dass das GCC nicht viel von «-Wextra» in «-Wall» aufgenommen hat. Glauben Sie mir, einige dieser Fahnen sind besonders nützlich . Zumindest befreien mich diese Warnungen von stundenlangem Debuggen.
Hi-Angel

1
Ich bin überrascht, dass niemand Code-Reviews in den Antworten erwähnt hat. Für mich wären Leute, die versuchen, sich in ein paar beschissene Hacks zu schleichen, durch Code-Reviews blockiert worden ...
dyesdyes

Antworten:


16

In der Praxis funktioniert jedoch nichts so gut wie erwartet, und das Projekt läuft seit einem halben Jahr auf DEFCON 1. Jetzt freuen sich die meisten meiner Kollegen, wenn sie um 18 Uhr nach Hause gehen können - am Sonntag.

Dies ist sicherlich ein guter Teil Ihres Problems. Ein Softwareentwickler kann nicht länger als 40 Stunden pro Woche produktiv arbeiten. Wenn Sie darüber hinausgehen, beeinträchtigen Sie Ihre Arbeitskapazität erheblich - bis zu dem Punkt, an dem selbst 80 Stunden / Woche für das Projekt nur noch einen geringen Wert haben, und manchmal können Projekte sogar rückläufig sein, weil das Team mehr Fehler verursacht als sie können reparieren. Wenn Sie ein halbes Jahr lang 60 Stunden / Woche oder mehr geleistet haben, dann braucht Ihr gesamtes Team eine gute, lange Pause, um mit 40 Stunden / Woche wiederzukommen. Sie können nichts mit einer Belegschaft lösen , die kaum in der Lage ist, auf die Tastatur zu drücken, weil sie so überarbeitet ist.

Die proprietären Tools listen jedoch Dinge wie implizite Casts und die Größe eines String-Literal auf. Implizite Casts werden ebenfalls in ihr Stylebook aufgenommen.

Sie müssen das Tool wirklich entweder ganz fallen lassen oder neu konfigurieren / ersetzen. Das Warnen bei jeder impliziten Besetzung ist viel zu viel für jeden, um damit fertig zu werden.


Könnten Sie bitte einen Hinweis auf eine Studie mit einer wöchentlichen Höchstdauer von 40 Stunden geben?

11
hier und hier , nur für den Anfang. Es ist sehr gut dokumentiert, dass Sie nicht mehr als 40 Stunden pro Woche produktiv arbeiten können. Ein einfaches Google findet unzählige Artikel.
DeadMG

5
Zwei kleine, aber meiner Meinung nach wichtige Korrekturen: Das Limit von 40 Stunden / Woche ist ein ungefährer Durchschnittswert, und die Regel gilt nur für längere Zeiträume. Es ist in Ordnung, dass ein Team vor einem wichtigen Stichtag zusätzliche Stunden einlegt und sich anschließend erholt (möglicherweise sogar einige Tage frei nimmt). Das Limit variiert auch zwischen den Menschen und im Laufe der Zeit - einige können problemlos 43 Stunden pro Woche arbeiten, andere nur 35, und einer ist in einigen Wochen produktiver als andere. Es wird jedoch ernsthafte Probleme bereiten, wenn mehr als ein paar Wochen hintereinander erhebliche Überstunden geleistet werden.
Péter Török

13

Ich arbeite in einer Firma, die Joel Test mit 11 Punkten bewertet - zumindest auf dem Papier.

Dieser Test ist für Softwareunternehmen nur geringfügig relevant. Ich verstehe den Hype nicht. Sie können 12 Punkte erzielen und trotzdem 100% Mistprogrammierer haben. Menschen sind weit mehr wichtig als Werkzeuge.

Die proprietären Tools listen jedoch Dinge wie implizite Casts und die Größe eines String-Literal auf. Implizite Casts werden ebenfalls in ihr Stylebook aufgenommen. Die übliche Praxis ist, dass die Leute dazu gedrängt werden, jede einzelne Warnung zum Schweigen zu bringen. Beachten Sie, dass dies Warnungen ausschließt, bei denen es sich überwiegend um Fehlalarme handelt. Dies ist nicht das Problem.

Dies ist das größte Problem bei allen statischen Analysegeräten: zu viele Fehlalarme. Die einzige Möglichkeit, damit umzugehen, besteht darin , im Detail zu erfahren, warum das Tool eine Warnung für ein bestimmtes Problem ausgibt. Nur dann können Sie qualifizierte Annahmen treffen, ob eine Warnung falsch ist oder nicht.

Für die spezielle Besetzung von impliziten Typumwandlungen, ist es dort , weil einige sehr häufig, subtil und gefährliche Fehler in der C - Sprache, die durch die beide (schwachsinnig) implizite Typen Förderung Regeln in C sind sie formal als bekannt die ganze Zahl Förderung Regeln und die üblichen arithmetischen Umrechnungen . Ich denke, weniger als einer von zehn professionellen C-Programmierern kann erklären, was diese beiden Regeln tun und was nicht. Und doch sind diese Regeln äußerst grundlegend und werden in jedem normalen C-Programm tausende Male zwischen den Zeilen angewendet.

Der MISRA-C-Standard hat ein ganzes Kapitel gewidmet, um diese gefährlichen impliziten Konvertierungsregeln zu erläutern. Anschließend wurden zahlreiche recht komplexe Regeln hinzugefügt, um Fehler zu vermeiden, die durch implizite Konvertierung verursacht werden. Dies hatte erhebliche Auswirkungen auf alle statischen Analysegeräte auf dem Markt.

Ich würde jedem C-Programmierer empfehlen, dieses MISRA-C-Kapitel oder zumindest die beiden von mir erwähnten Promotion-Regeln von Google zu lesen und so viel wie möglich darüber zu lesen. Sie können den statischen Analysator nur ignorieren, wenn Sie alles über diese Regeln wissen.

Nun, ich glaube nicht wirklich, dass diese Firma gerettet werden kann. Ich würde jedoch gerne wissen, ob es eine bessere, am besten funktionierende Möglichkeit gibt, die "Pro" -Tools zu verwenden, oder ob ich sie ganz vermeiden sollte, falls ich in Zukunft die Entscheidung treffen sollte.

Eine Lösung, bei der nicht alle Programmierer Genies sind, die nichts falsch machen können. Denn wenn ja, müssen die Werkzeuge nicht unbedingt verwendet werden.

Es gibt keinen einfachen Weg daran vorbei. Das eigentliche Problem ist eigentlich nicht das Tool, sondern die obskure C-Sprache. Auf den ersten Blick scheint es eine einfache Sprache zu sein, aber es gibt viele unlogische und seltsame Mechanismen zwischen den Zeilen. Und es gibt Hunderte von Fällen von undefiniertem / nicht spezifiziertem / implizit spezifischem Verhalten in der Sprache. Die meisten von ihnen müssen Sie lernen und vermeiden.

Sie müssen also entweder ein erfahrener C-Programmierer sein, der all diese undurchsichtigen Warnungen versteht, oder Sie müssen mit mindestens einer solchen Person in einem Team sein. Unternehmen, die nur eine Reihe von Junior-Programmierern einstellen, die noch keine Erfahrung im Team haben, sollten diese Tools nicht verwenden und auch nicht mit hochintegrierter Softwareentwicklung arbeiten.


Ich habe den Test von Anfang an mit einer Prise Salz gemacht, aber es ist kein Tool zum Testen von Programmierern, sondern ein Tool zum Testen von Arbeitgebern. Ich vermute, Sie könnten geeignete Mitarbeiter als "beste Werkzeuge, die man mit Geld bezahlen kann" bezeichnen. Und ich nehme Ihre Antwort, um die SA-Werkzeuge wegzuwerfen und besser anzustellen und / oder zu trainieren. Der erste Punkt scheint der gemeinsame Nenner zu sein.

@qpr Es testet auch nicht den Arbeitgeber, sondern nur die Bereitschaft des Arbeitgebers, Geld für die Softwareentwicklung auszugeben. Dinge wie Einstellungsverfahren, Unternehmensziele, Marktkenntnisse usw. usw. werden nicht erwähnt. Ich denke, die meisten "IT-Bubble" -Unternehmen würden bei diesem Test 12 Punkte erzielen, wobei ein Management nicht einmal weiß, welche Produkte entwickelt werden oder ob es überhaupt einen Markt für sie gibt.

4

Es ist nicht klar, ob Sie sich fragen, wie Sie das Problem beheben können oder wie Sie es überhaupt hätten vermeiden können. Ich gehe von letzterem aus.

Es hört sich so an, als hätten Sie sich auf statische Analysen als primäres Mittel zum Erkennen und Vermeiden von Fehlern verlassen. Vielleicht wäre es besser gewesen, wenn Sie sich mehr auf Unit-Tests und dynamische Tools wie Speicherprüfungen konzentriert hätten.

Es ist eine schlechte Idee, sich auf ein Tool zu verlassen, das viele False Positives generiert, insbesondere wenn Sie diese False Positives nicht unterdrücken können. Es ermutigt müde / überarbeitete (oder faule) Programmierer, "Korrekturen" vorzunehmen, damit die Warnungen verschwinden. Wenn Sie Fehlalarme (z. B. mit Kommentaren) nicht selektiv unterdrücken oder den Regelsatz nicht anpassen können, benötigen Sie ein besseres Tool. Oder zumindest sollten Sie es nur sparsam verwenden.

Es hört sich so an, als ob Sie ein Problem damit haben, dass Menschen sorglos sind und / oder aufgrund von Überarbeitung Fehler machen. Vielleicht hättest du mehr Zeit und Mühe in die Codeüberprüfung investieren sollen. Dies richtet sich direkt an Ihre Beobachtung, dass Programmierer keine Genies sind.

Schließlich hört es sich so an, als ob Sie unter unrealistischen Fristen gelitten haben, arme Leute Mittel beschaffen und / oder Anforderungen verlagern. Dies ist ein Managementproblem und muss auf dieser Ebene angegangen werden. Andernfalls besteht ein erheblich erhöhtes Risiko für ein Scheitern des Projekts und einen langfristigen Schaden für die Produktivität und die Arbeitsmoral der Mitarbeiter.


3

Zusätzlich zu der hervorragenden Antwort von user29079 möchte ich noch einen Mangel der C-Sprache hinzufügen, der das Problem noch verstärkt. Dieser Mangel war mir erst bewusst, als ich zu Java überging.

Der Zweck einer Warnung ist es, den Verfasser und zukünftige Leser des Codes auf die Tatsache aufmerksam zu machen, dass etwas faul ist. Das ist als Konzept völlig in Ordnung: Je mehr Warnungen Sie aktiviert haben, desto fauler werden die Dinge, die Sie entdecken.

Was absolut falsch ist , ist die Vorstellung, dass jedes einzelne kleine Fischding um jeden Preis repariert werden muss, indem der Code geändert wird . Dies ist der Grund für das Problem, das das OP beschreibt: Die verpatzten Versuche, schnell Warnungen auszulösen, gehen verloren, indem der Code geändert wird, der einwandfrei funktioniert.

Gleichzeitig möchten wir nicht, dass unser Code bei jeder Kompilierung Hunderte von Warnungen ausgibt, da Warnungen bald bedeutungslos werden und niemand mehr auf neue Warnungen achtet.

Dies scheint also ein Fall von Zielkonflikten zu sein; ein Widerspruch.

Eine sehr gute Lösung für dieses scheinbar unmögliche Dilemma besteht darin, eine bestimmte Warnung von Aussage zu Aussage selektiv unterdrücken zu können, damit wir sie genau dort unterdrücken können, wo wir darauf hinweisen wollen, dass wir wirklich wissen, was wir tun, ohne Code ändern zu müssen.

Java hat eine schöne Lösung dafür, mit der @SuppressWarnings( "" )Annotation. Wenn Sie beispielsweise in Java eine so genannte ungeprüfte Konvertierung durchführen , gibt der Compiler eine Warnung aus, um Sie darauf aufmerksam zu machen. Sie überprüfen diese und stellen fest, dass dies einer der Fälle ist, in denen Sie wissen, was Sie tun. So stellen Sie der beleidigenden Aussage eine @SuppressWarnings( "unchecked" )Anmerkung voran, die sich nur auf die unmittelbar darauf folgende Aussage auswirkt , und Sie fahren mit Ihrem Leben fort.

Die Warnung verschwindet, der Code bleibt unverändert, und die durch Syntaxhervorhebung grün hinterlegte Unterdrückungsannotation dokumentiert, dass eine zweifelhafte Konvertierung stattfindet, die der Autor jedoch verspricht, ist gut. (*) Alle sind glücklich.

In Java können Sie Funktionen sogar einzelne Parameter voranstellen @SuppressWarnings(), um eine bestimmte Warnung zu deaktivieren, die nur für diesen bestimmten Parameter ausgegeben werden kann.

Soweit mir bekannt ist, hat C jedoch nie einen Standardmechanismus zur selektiven Unterdrückung von Warnungen in Anweisungen unterstützt, und bestimmte Compiler, die ihre eigenen proprietären Mechanismen implementiert haben, haben dies auf geschickte Weise getan, z. B. die #pragma warning (nnn:N)Anweisungen von Microsoft C. Das Problem mit diesen Anweisungen ist, dass Sie zwei Zeilen von Anweisungen benötigen, um eine Warnung für eine einzelne Anweisung zu unterdrücken und diese Warnung für nachfolgende Anweisungen aktiviert zu lassen. Daher ist es sehr unwahrscheinlich, dass C-Programmierer die Gewohnheit der Unterdrückung einer Warnung auf der Basis einzelner Anweisungen aufgreifen, selbst wenn sie wissen, dass diese spezielle Warnung für diese spezielle Anweisung in Ordnung ist.


(*) Jemand könnte argumentieren, dass, wenn Sie dies zulassen, jeder Programmierer im Haus Warnungen unterdrückt, ohne darüber nachzudenken; Die Antwort darauf ist, dass Sie alles tun, um den Programmierern zu helfen, ihre Arbeit besser zu machen, aber es gibt nichts, was Sie tun können, wenn sie sich aktiv entschließen, Sie zu sabotieren.


Mit anderen Worten, während das Ändern der Quelle , um jede letzte Warnung zu entfernen, der Schlüssel zu einer guten Praxis ist, ist das Ändern des kompilierbaren Codes nicht der Fall , da damit einfacher Code beseitigt wird, der ohne triftigen Grund einfach korrekt ist. Gute Auszeichnung.
Nathan Tuggy

2

Ich würde sagen (ohne die Details zu kennen), dass Ihr Unternehmen größere Fehler gemacht hat und dies ist nur das Symptom: Es hat die Domäne der produzierten Software nicht richtig bestimmt , das Team nicht richtig geführt und vernünftige Ziele definiert.

Wenn die Software, die Ihr Team schreibt, für das menschliche Leben von entscheidender Bedeutung ist, sind statische Analysewerkzeuge wichtig und nützlich. Da die "Kosten" eines Fehlers, gemessen in Geld (ignoriert, wie zynisch das ist), hoch sind, sind für den Job spezielle Werkzeuge erforderlich. Es gibt Richtlinien für C und C ++ für die sichere Verwendung der Sprachfunktionen (lesen Sie, was zu vermeiden ist und wie weit Sie gehen müssen, um dies zu vermeiden).
In einer solchen Situation ist es jedoch eine sehr schlechte Idee, Mitarbeiter am Sonntag arbeiten zu lassen. Aus dem von Ihnen angegebenen Kontext schätze ich außerdem, dass schlampige Arbeit nicht selten vorkommt. Wenn dies der Fall ist, ist das Problem sehr, sehr großgroß, und Ihr Management versucht, es mit "besseren" Tools zu lösen. Leider funktionieren die Dinge nicht so. Wenn ich kurz davor bin, etwas zu korrigieren, würde ich sogar vorschlagen, dass Sie sich nach einem anderen Job umsehen. Schlecht gemachte unternehmenskritische Software kann Sie verfolgen und Ihren beruflichen Ruf ruinieren, ganz zu schweigen von potenziellen Rechtsstreitigkeiten.

Wenn Ihr Team dagegen etwas schreibt, das weitaus weniger kritisch ist, verlangsamen statische Analysetools mit einer hohen Falsch-Positiv-Rate Sie nur, und wie Sie bereits bemerkt haben, reagieren die Leute in der Regel mit Finden des lokalen Maximums in ihrer Wirksamkeit, in diesem Fall durch einfaches Umgehen der Warnungen, anstatt zu versuchen, den zugrunde liegenden Grund zu bestimmen. In Ihrer Situation kann die Verwendung dieser Tools die Qualität des Quellcodes beeinträchtigen, und sie sollten im Allgemeinen vermieden werden.

Wenn Sie ein Software-Team verwalten müssen, das C- oder C ++ - Code schreibt, sollten Sie zunächst die wichtigsten Projektziele festlegen. Wenn das Schreiben von fehlerfreiem Code von äußerster Wichtigkeit ist (z. B. passt die neue superfrohe Social-App für iOS und Android nicht dazu), verwenden Sie statische Analysen und gehen Sie möglicherweise sogar bis zur formalen Spezifikation und formalen Verifizierung. In diesem Fall ist es jedoch weitaus wichtiger, gute Programmierer auszuwählen und sie in einer vernünftigen Umgebung mit angemessener Arbeitsbelastung und angemessener 40-Stunden-Woche arbeiten zu lassen.

Menschen können nicht verantwortungsbewusst arbeiten, wenn sie wie Sklaven behandelt werden (und jemand, der gerade meine Ferien verbringt, ist genau das), und gute Programmierer werden sich einfach weigern, dies regelmäßig zu tun, es sei denn, sie wissen es nicht besser (und wenn sie gut sind, stehen die Chancen gut) tun sie).

Fazit: Ermitteln Sie Ihre Ziele und bestimmen Sie dann die Tools und den Prozess, den Sie verwenden. Lassen Sie sich nicht von den verfügbaren Tools den Prozess definieren (dh die Ziele festlegen), da das (schlechte) Management Sie möglicherweise zwingen möchte.


1

Wie in der Antwort von k.steff angegeben, sind statische Analyse-Tools für 'C' nützlich, wenn Sie Software in einer kritischen Situation erstellen (Flugzeugsoftware) und sie müssen ab dem ersten Tag (nicht nach Monaten der Entwicklung, wenn ein nicht reproduzierbarer Fehler auftritt) verwendet werden ).

Die späte Verwendung solcher Tools im Entwicklungsprozess ist normalerweise ein Zeichen für schlechte Designentscheidungen zu Beginn des Prozesses.

In nicht-kritischer Software sind diese Tools nützlich, um:
- die Verwaltung von Maßnahmen zu verbessern, sie als nützlich zu erachten (wir haben etwas getan, wir haben viel Geld ausgegeben, um die Software zu reparieren). Sie erhalten Aktionen, die in ihren Powerpoint-Berichten einfach auszuführen sind.
- Beschäftige die "giftigen" Entwickler. Lassen Sie sie das Tool konfigurieren und die Tool-Ergebnisse analysieren, damit Sie Zeit haben, ihre bösen Fehler zu beheben.
Kodierungsregeln erzwingen. In diesem Fall muss es ab dem ersten Tag verwendet werden. Ein gutes Tool zur Codeüberprüfung ist jedoch möglicherweise die bessere Wahl.

Meiner Meinung nach müssen Sie solche teuren und zeitaufwendigen Werkzeuge meiden oder sie verwenden, um die "giftigen" Leute zu beschäftigen.


1

Ich arbeite in einer Firma, die Joel Test mit 11 Punkten bewertet - zumindest auf dem Papier.

Die Validierung durch den Joel-Test ist kein Maßstab für bewährte Verfahren. Die Invalidierung durch den Joel-Test ist jedoch ein Maß für schlechte / fehlende Praktiken. Mit anderen Worten, es kann als notwendig, aber nicht ausreichend angesehen werden.

Jetzt freuen sich die meisten meiner Kollegen, wenn sie um 18 Uhr nach Hause gehen können - am Sonntag.

Sie haben anscheinend ein Verwaltungsproblem. Systematische Überstunden sind keine Lösung, um Dinge zu erledigen. Wenn überhaupt, ist es eine Lösung, um Dinge so aussehen zu lassen, als würden sie funktionieren und technische Schulden akkumulieren.

Nun, ich glaube nicht wirklich, dass diese Firma gerettet werden kann. Ich würde jedoch gerne wissen, ob es eine bessere, am besten funktionierende Möglichkeit gibt, die "Pro" -Tools zu verwenden, oder ob ich sie ganz vermeiden sollte, falls ich in Zukunft die Entscheidung treffen sollte.

Ja, es gibt eine Möglichkeit, die statische Code-Analyse auf vernünftige Weise zu verwenden.

Sie können und bieten in der Regel viel Wert. Sie müssen sich nur daran erinnern, dass (wie Compiler-Warnungen) ein statisches Analysetool (höchstens) Hinweise auf einen Fehler liefern kann - keine Fehlerberichte und überhaupt keine Gewissheit.

Es hört sich so an, als würden Ihre Entscheidungsträger statische Analyseflags mit Anwendungsfehlern verwechseln.

Implizite Casts werden ebenfalls in ihr Stylebook aufgenommen.

Dies klingt nach einem Managementkompetenzproblem, nicht nach einem statischen Analyseproblem.

Das Ergebnis ist:

Die Leute fügen jedem R-Wert und jedem Argument einen Typ-Cast hinzu und verbergen dabei echte, problematische Typenkonflikte.

Die Leute melden sich mit einem Fehler oder verwenden ein anderes problematisches Sprachmerkmal (strlen statt sizeof, strncpy statt strcpy usw.).

Die Warnungen werden stummgeschaltet.

Die Fehlerberichte rollen herein.

All dies sind Möglichkeiten, um die regelmäßigen Berichte gut aussehen zu lassen, nicht Möglichkeiten, um die Probleme im Code zu beheben (es sieht so aus, als hätten Sie wieder ein Problem mit der Managementkompetenz).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.