it-swarm.it

Quali cose suonano all'istante quando suona il codice?

Ho partecipato a un evento di artigianato del software un paio di settimane fa e uno dei commenti fatti è stato "Sono sicuro che tutti riconosciamo il codice errato quando lo vediamo" e tutti hanno annuito in modo sagace senza ulteriori discussioni.

Questo genere di cose mi preoccupa sempre perché c'è quel vero che tutti pensano di essere un guidatore sopra la media. Anche se penso di poter riconoscere il codice errato, mi piacerebbe saperne di più su ciò che gli altri considerano odori di codice poiché raramente è discusso in dettaglio nei blog delle persone e solo in una manciata di libri. In particolare, penso che sarebbe interessante sentire qualcosa che ha un odore di codice in una lingua ma non in un'altra.

Inizierò con uno semplice:

Codice nel controllo del codice sorgente che ha un'alta percentuale di codice commentato - perché è lì? doveva essere cancellato? è un lavoro a metà finito? forse non avrebbe dovuto essere commentato e fatto solo quando qualcuno stava testando qualcosa? Personalmente trovo questo tipo di cose davvero fastidioso anche se è solo la strana linea qua e là, ma quando vedi blocchi di grandi dimensioni intervallati dal resto del codice è totalmente inaccettabile. Di solito è anche un'indicazione che è probabile che anche il resto del codice sia di dubbia qualità.

98
FinnNk
/* Fuck this error */

In genere trovato all'interno di un'assurdità try..catch blocco, tende ad attirare la mia attenzione. Quasi oltre a /* Not sure what this does, but removing it breaks the build */.

Un altro paio di cose:

  • Più istruzioni if complesse nidificate
  • Blocchi Try-catch utilizzati per determinare un flusso logico su base regolare
  • Funzioni con nomi generici process, data, change, rework, modify
  • Sei o sette diversi stili di controventatura in 100 linee

Uno che ho appena trovato:

/* Stupid database */
$conn = null;
while(!$conn) {
    $conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");

Bene, perché dover forzare le tue connessioni MySQL è il modo giusto di fare le cose. Si scopre che il database stava riscontrando problemi con il numero di connessioni, quindi hanno continuato a scadere. Invece di eseguire il debug di questo, hanno semplicemente tentato ancora e ancora finché non ha funzionato.

128
Josh K

La bandiera rossa principale per me sono i blocchi di codice duplicati, perché mostra che la persona o non capisce i fondamenti della programmazione o era troppo spaventata per apportare le modifiche appropriate a una base di codice esistente.

Contavo anche la mancanza di commenti come una bandiera rossa, ma di recente ho lavorato su un ottimo codice senza commenti che ho rimandato.

104
Ben Hughes

Codice che cerca di mostrare quanto sia intelligente il programmatore, nonostante non aggiunga alcun valore reale:

x ^= y ^= x ^= y;
74
Rei Miyasaka
  • 20.000 funzioni di linea (esagerazione). Qualsiasi funzione che richiede più di un paio di schermate necessita di un nuovo factoring.

  • Sulla stessa linea, file di classe che sembrano andare avanti per sempre. Probabilmente ci sono alcuni concetti che potrebbero essere astratti in classi che chiarirebbero lo scopo e la funzione della classe originale e probabilmente dove viene usata, a meno che non siano tutti metodi interni.

  • variabili non descrittive, non banali o troppe variabili banali non descrittive. Questi fanno dedurre ciò che sta realmente accadendo un enigma.

62
{ Let it Leak, people have good enough computers to cope these days }

Quel che è peggio è che proviene da una biblioteca commerciale!

61
Reallyethical

Commenti così dettagliati che se ci fosse un compilatore inglese, si compilerà e funzionerebbe perfettamente, ma non descrive nulla che il codice non abbia.

//Copy the value of y to temp.
temp = y;
//Copy the value of x to y.
y = x;
//Copy the value of temp to x.
x = temp;

Inoltre, i commenti sul codice che avrebbero potuto essere eliminati se il codice avesse aderito ad alcune linee guida di base:

//Set the age of the user to 13.
a = 13;
53
Rei Miyasaka

Codice che genera avvisi quando viene compilato.

42
Rei Miyasaka

Funziona con numeri nel nome invece di avere nomi descrittivi, come:

void doSomething()
{
}

void doSomething2()
{
}

Per favore, fai in modo che i nomi delle funzioni significino qualcosa! Se doSomething e doSomething2 fanno cose simili, usa nomi di funzioni che differenziano le differenze. Se doSomething2 è una rottura delle funzionalità di doSomething, chiamalo per la sua funzionalità.

36
Wonko the Sane

numeri magici o stringhe magiche.

   if (accountBalance>200) { sendInvoice(...); }

   salesPrice *= 0.9;   //apply discount    

   if (invoiceStatus=="Overdue") { reportToCreditAgency(); }
36
JohnFx
  • Forse non è il peggiore, ma mostra chiaramente il livello degli implementatori:

    if(something == true) 
    
  • Se una lingua ha un costrutto for loop o iteratore, l'utilizzo di un ciclo while dimostra anche il livello di comprensione della lingua da parte degli implementatori:

    count = 0; 
    while(count < items.size()){
       do stuff
       count ++; 
    }
    
    for(i = 0; i < items.size(); i++){
      do stuff 
    }
    //Sure this is not terrible but use the language the way it was meant to be used.
    
  • La cattiva ortografia/grammatica nella documentazione/nei commenti mangia quasi quanto il codice stesso. Il motivo è dovuto al fatto che il codice era destinato alla lettura umana e all'esecuzione delle macchine. Questo è il motivo per cui usiamo linguaggi di alto livello, se la tua documentazione è difficile da superare, mi fa preventivamente formare un'opinione negativa della base di codice senza guardarla.

36
Chris

Quello che noto immediatamente è la frequenza di blocchi di codice profondamente nidificati (if's, while's, ecc.). Se il codice è frequentemente profondo più di due o tre livelli, questo è un segno di un problema di progettazione/logica. E se arriva come 8 nidi in profondità, è meglio che ci sia una buona ragione per non romperlo.

29
GrandmasterB

Durante la valutazione del programma di uno studente, a volte posso dire in un momento in stile "battito di ciglia". Questi sono gli indizi istantanei:

  • Formattazione scadente o incoerente
  • Più di due righe vuote di fila
  • Convenzioni di denominazione non standard o incoerenti
  • Codice ripetuto, più ripetute sono le parole, più forte è l'avvertimento
  • Quello che dovrebbe essere un semplice pezzo di codice è eccessivamente complicato (ad esempio, controllando gli argomenti passati al principale in modo contorto)

Raramente le mie prime impressioni sono errate e queste campane di avvertimento hanno ragione 95% delle volte. Per un'eccezione, uno studente che non conosceva il linguaggio stava usando uno stile di un linguaggio di programmazione diverso. Scavare e rileggere il loro stile nel linguaggio dell'altra lingua mi ha tolto il campanello d'allarme e lo studente ha ottenuto il pieno credito. Ma tali eccezioni sono rare.

Quando si considera un codice più avanzato, questi sono i miei altri avvertimenti:

  • La presenza di molte Java che sono solo "strutture" per contenere i dati. Non importa se il i campi sono pubblici o privati ​​e utilizzano getter/setter, probabilmente non fa ancora parte di un progetto ben congegnato.
  • Classi che hanno nomi scadenti, come essere semplicemente uno spazio dei nomi e non c'è vera coesione nel codice
  • Riferimento a modelli di progettazione che non sono nemmeno utilizzati nel codice
  • Gestori di eccezioni vuoti senza spiegazione
  • Quando estraggo il codice in Eclipse, centinaia di "avvisi" gialli allineano il codice, principalmente a causa di importazioni o variabili non utilizzate

In termini di stile, in genere non mi piace vedere:

  • Commenti Javadoc che fanno solo eco al codice

Questi sono solo indizi al codice errato. A volte ciò che può sembrare un cattivo codice in realtà non lo è, perché non conosci le intenzioni del programmatore. Ad esempio, potrebbe esserci una buona ragione per cui qualcosa sembra eccessivamente complesso: potrebbe esserci stata un'altra considerazione in gioco.

28
Macneil

Preferito preferito/animale domestico: IDE nomi generati che vengono inseriti. Se TextBox1 è una variabile importante e importante nel tuo sistema, hai un'altra cosa in arrivo, la revisione del codice.

25
Wyatt Barnett

Variabili completamente inutilizzate, in particolare quando la variabile ha un nome simile ai nomi delle variabili utilizzati.

25
C. Ross

Molte persone hanno menzionato:

//TODO: [something not implemented]

Mentre vorrei che le cose fossero implementate, almeno hanno preso nota. Quello che penso sia peggio è:

//TODO: [something that is already implemented]

I Todo sono inutili e confusi se non ti preoccupi mai di rimuoverli!

21
Morgan Herlocker

Congiunzioni nei nomi dei metodi:

public void addEmployeeAndUpdatePayrate(...) 


public int getSalaryOrHourlyPay(int Employee) ....

Chiarimento: il motivo per cui suona un campanello d'allarme è che indica che il metodo probabilmente viola il principio di responsabilità singola .

20
JohnFx

Un metodo che mi richiede di scorrere verso il basso per leggere tutto.

20
BradB

Collegando ovviamente il codice sorgente GPL a un programma commerciale, a codice chiuso.

Non solo crea un problema legale immediato, ma nella mia esperienza, di solito indica disattenzione o disinteresse che si riflette anche altrove nel codice.

13
Bob Murphy

Lingua agnostica:

  • TODO: not implemented
  • int function(...) { return -1; } (uguale a "non implementato")
  • Generare un'eccezione per un motivo non eccezionale.
  • Uso improprio o incoerente di 0, -1 O null come valori di restituzione eccezionali.
  • Asserzioni senza un commento convincente che dice perché non dovrebbe mai fallire.

Specifico per la lingua (C++):

  • Macro C++ in minuscolo.
  • Variabili C++ statiche o globali.
  • Variabili non inizializzate o non utilizzate.
  • Qualsiasi array new Apparentemente non sicuro per RAII.
  • Qualsiasi utilizzo di array o puntatori apparentemente non sicuro ai limiti. Questo include printf.
  • Qualsiasi utilizzo della parte non inizializzata di un array.

specifico di Microsoft C++:

  • Qualsiasi nome identificativo che si scontra con una macro già definita da uno qualsiasi dei file di intestazione di Microsoft SDK.
  • In generale, qualsiasi utilizzo dell'API Win32 è una grande fonte di campanelli d'allarme. Tenere sempre aperto MSDN e cercare gli argomenti/restituire le definizioni dei valori in caso di dubbio. (Edited)

specifico C++/OOP:

  • Ereditarietà dell'implementazione (classe concreta) in cui la classe genitore ha metodi sia virtuali che non virtuali, senza una chiara distinzione concettuale evidente tra ciò che dovrebbe/non dovrebbe essere virtuale.
9
rwong

Utilizzo di molti blocchi di testo anziché enumerazioni o variabili definite a livello globale.

Non bene:

if (itemType == "Student") { ... }

Meglio:

private enum itemTypeEnum {
  Student,
  Teacher
}
if (itemType == itemTypeEnum.Student.ToString()) { ... }

Migliore:

private itemTypeEnum itemType;
...
if (itemType == itemTypeEnum.Student) { ... }
8
Yaakov Ellis

Bizzarro stile di rientro.

Ci sono un paio di stili molto popolari e le persone porteranno quel dibattito alla Tomba. Ma a volte vedo qualcuno che usa uno stile di rientro davvero raro, o addirittura cresciuto in casa. Questo è un segno che probabilmente non hanno codificato con nessuno diverso da loro stessi.

8
Ken

Parametri debolmente digitati o valori di ritorno sui metodi.

public DataTable GetEmployees() {...}

public DateTime getHireDate(DataTable EmployeeInfo) {...}

public void FireEmployee(Object EmployeeObjectOrEmployeeID) {...}
8
JohnFx

Odore di codice: non seguire le migliori pratiche

Questo genere di cose mi preoccupa sempre perché c'è quel vero che tutti pensano di essere un guidatore sopra la media.

Ecco un lampo di notizie per te: il 50% della popolazione mondiale è al di sotto della media dell'intelligence. Ok, quindi alcune persone avrebbero un'intelligenza esattamente nella media, ma non facciamoci schizzinosi. Inoltre, uno degli effetti collaterali della stupidità è che non puoi riconoscere la tua stessa stupidità! Le cose non sembrano così belle se si combinano queste affermazioni.

Quali cose suonano all'istante quando suona il codice?

Sono state menzionate molte cose positive e in generale sembra che non seguire le migliori pratiche sia un odore di codice.

Le migliori pratiche di solito non vengono inventate in modo casuale e spesso sono lì per un motivo. Molte volte può essere soggettivo, ma nella mia esperienza sono per lo più giustificati. Seguire le migliori pratiche non dovrebbe essere un problema, e se ti stai chiedendo perché sono come sono, cercalo piuttosto che ignorarlo e/o lamentarti di questo - forse è giustificato, forse no.

Un esempio di una buona pratica potrebbe essere l'uso dei ricci con ogni if-block, anche se contiene solo una riga:

if (something) {
    // whatever
}

Potresti non pensare che sia necessario, ma di recente leggi che è una delle principali fonti di bug. Sempre usando parentesi sono stati discussi anche su Stack Overflow , e verificare che if-istruzioni abbiano parentesi è anche una regola in PMD , un analizzatore di codice statico per Java.

Ricorda: "Perché è la migliore pratica" non è mai una risposta accettabile alla domanda "perché lo stai facendo?" Se non riesci a capire perché qualcosa è una buona pratica, allora non è una buona pratica, è una superstizione.

7
Vetle
  • Più operatori ternari messi insieme, quindi invece di assomigliare a un blocco if...else, Diventa un blocco if...else if...[...]...else
  • Nomi variabili lunghi senza sottolineatura o CamelCasing. Esempio da un codice che ho estratto: $lesseeloginaccountservice
  • Centinaia di righe di codice in un file, con pochi o nessun commento, e il codice è molto ovvio
  • Dichiarazioni if eccessivamente complicate. Esempio dal codice: if (!($lessee_obj instanceof Lessee && $lessee_obj != NULL)) che ho ridotto a if ($lessee_obj == null)
7
Tarka

Cattura delle eccezioni generali:

try {

 ...

} catch {
}

o

try {

 ...

} catch (Exception ex) {
}

Sovrautilizzo della regione

In genere, l'utilizzo di troppe regioni mi indica che le tue classi sono troppo grandi. È un flag di avvertimento che segnala che dovrei indagare di più su quel bit di codice.

6
Erik van Brakel

Qualcuno può pensare a un esempio in cui il codice dovrebbe legittimamente fare riferimento a un file in base al percorso assoluto?

6
Rei Miyasaka

Commenti che dicono "questo perché il design del sottosistema Froz è totalmente ottimizzato".

Questo va avanti per un intero paragrafo.

Spiegano che deve avvenire il seguente refattore.

Ma non l'ha fatto.

Ora, avrebbero potuto dirgli che non potevano cambiarlo dal loro capo in quel momento, a causa di problemi di tempo o di competenza, ma forse era perché le persone erano meschine.

Se un supervisore pensa che j.random. il programmatore non può fare un refactoring, quindi il supervisore dovrebbe farlo.

Ad ogni modo ciò accade, so che il codice è stato scritto da una squadra divisa, con possibili politiche di potere, e non hanno riformattato i progetti del sottosistema corrotto.

Storia vera. Potrebbe capitare a te.

6
Tim Williscroft
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...

Naturalmente senza alcun tipo di documentazione e il nidificato occasionale #defineS

5
Sven

Codice C++ con esplicite istruzioni di eliminazione (a meno che non stia osservando le viscere di un'implementazione del puntatore intelligente). 'delete' è il 'goto' della gestione della memoria IMHO .

Strettamente correlato a questo, codice come:

// Caller must take ownership
Thing* Foo::Bar()

(E considerati fortunato se c'è il commento!). Non è che i puntatori intelligenti siano la scienza missilistica. std::auto_ptr è fatto per questo genere di cose (documentando e applicando l'intento espresso nel commento) ed è stato parte del standard = da anni ormai.

Insieme, questi grida codice legacy non amato, o manutentori con una mentalità bloccata da qualche parte nei primi anni '90.

5
timday

Funzioni che reimplementano le funzionalità di base della lingua. Ad esempio, se vedi mai un metodo "getStringLength ()" in JavaScript invece di una chiamata alla proprietà ".length" di una stringa, sai che sei nei guai.

5
Ant

Convenzioni di denominazione delle classi che dimostrano una scarsa comprensione dell'astrazione che stanno tentando di creare. O che non definisce affatto un'astrazione.

Un esempio estremo viene in mente in una VB classe che ho visto una volta che si intitolava Data ed era lunga più di 30.000 righe ... nel primo Era una classe parziale suddivisa in almeno una mezza dozzina di altri file, la maggior parte dei metodi erano wrapper attorno a proc memorizzati con nomi come FindXByYWithZ().

Anche con esempi meno drammatici, sono sicuro che abbiamo appena "scaricato" la logica in una classe mal concepita, dato che ha un titolo del tutto generico, e se ne è pentita in seguito.

5
Bryan M.
ON ERROR RESUME NEXT

Dover mantenere Classic ASP sono purtroppo una necessità per la maggior parte degli sviluppatori ASP.NET, ma aprire un file include comune e vedere che in prima linea sta distruggendo l'anima.

4
richeym

Quando non ci sono commenti o documentazione su ciò che il codice fa o dovrebbe fare (cioè "il codice è la documentazione").

Metodi o variabili con un numero come suffisso (ad es. Login2 ()).

4
leson
try
{
//do something
}
catch{}
3
Tom Squires

Codice che non può mai, inserire logicamente il percorso di esecuzione.

var product = repository.FindProduct(id);

log.Info("Found product " + product.Name);

if (product != null)
{
    // This will always happen
}
else
{
    // **This won't ever happen**
}

o

if (messages.Count > 0)
{
    // Do stuff with messages
}
else if (messages.Count == 1)
{
    // **I hope this code isn't important...**
}
3
rmac
  • Inserendo ogni variabile locale nelle prime righe del blocco del metodo. Soprattutto in combinazione con metodi lunghi.
  • Utilizzo di variabili booleane per interrompere loop/saltare iterazioni invece di utilizzare semplicemente break/continue
3
Oliver Weiler

Dalla mia prospettiva incentrata su Java:

  • Stile di codifica non standard.
  • Variabili non private.
  • Manca final nei campi.
  • Inutile o abusivo dell'eredità.
  • Enormi classi o blocchi di codice.
  • Troppi commenti (probabilmente sono solo un pio desiderio).
  • Registrazione non strutturata.
  • Getter e setter (le interfacce dovrebbero riguardare il comportamento).
  • Dati duplicati.
  • Strane dipendenze.
  • Statica, compresi i thread-globals.
  • Per il codice multi-thread, parti della stessa classe che dovrebbero essere eseguite in thread diversi (in particolare il codice GUI).
  • Codice morto.
  • Manipolazione di stringhe mescolata con altro codice.
  • Generalmente mescolando strati (cose di livello superiore, combinate con l'iterazione su una serie di primitive o la gestione dei thread, per esempio).
  • Qualsiasi uso della riflessione.
  • catch blocca senza codice utile (non valido: commenti, printf, registrazione o semplicemente vuoto).
3

Utilizzo di un oggetto nascosto nell'interfaccia utente (ad es. Una casella di testo) per memorizzare un valore anziché definire una variabile con ambito e di tipo appropriato.

2
MartW

Ogni volta che leggo quanto segue:

//Don't put in negative numbers or it will crash the program.

O qualcosa di simile. In tal caso, fai una dichiarazione! Fai sapere al debugger che durante il runtime non desideri quei valori e assicurati che il codice definisca il contratto con il chiamante.

2
wheaties

Questo tipo di codice:

        if (pflayerdef.DefinitionExpression == "NM_FIELD = '  '" || One.Two.nmEA == "" || 
            One.Two.nmEA == " " || One.Two.nmEA == null ||
            One.Two.nmEA == "  ")
        {                
            MessageBox.Show("BAD CODE");
            return;
        }

Questo proviene da una vera base di codice di produzione live!

2
George Silva

Per quanto riguarda i numeri magici: sono cattivi se vengono utilizzati in luoghi diversi e modificarlo richiede di sincronizzarlo in più punti. Ma un numero in un posto non è peggio che avere una costante per indicare un numero che è ancora usato in un posto.

Inoltre, le costanti potrebbero non avere molto spazio nella tua applicazione. In molte app di database, queste cose dovrebbero essere archiviate nel database secondo le app o le impostazioni dell'utente. E per completare la loro implementazione implicano questa impostazione e un posto nell'interfaccia utente e una nota nella documentazione per l'utente finale ... tutto ciò è una specie di ingegnerizzazione eccessiva e uno spreco di risorse se tutti sono perfettamente felici quando il numero è 5 ( e 5 lo è.)

Penso che puoi lasciare numeri e stringhe in posizione fino a quando non è necessario utilizzare questo numero al di fuori di quel posto. Quindi è il momento di riformattare le cose in un design più flessibile.

Per quanto riguarda le stringhe ... Conosco gli argomenti, ma questo è un altro posto in cui non ha senso fare una conversione da una stringa a una costante. Soprattutto se le stringhe in atto provengono comunque da un'implementazione costante (ad esempio, le importazioni che vengono generate da un'applicazione esterna e hanno una stringa di stato che è breve e riconoscibile, proprio come "In ritardo"). è molto utile convertire "Scaduto" in STATUS_OVERDUE quando viene comunque utilizzato in un solo posto.

Sono molto incline a non aggiungere complessità se non crea effettivamente i benefici necessari in termini di flessibilità, riutilizzo o controllo degli errori. Quando hai bisogno della flessibilità, codificala nel modo giusto (il fattore rifattore). Ma se non è necessario ...

2
Inca

Codice strettamente accoppiato. Soprattutto quando vedi molte cose hardcoded (nomi di stampanti di rete, indirizzi IP, ecc.) Nel mezzo del codice. Questi dovrebbero essere in un file di configurazione o anche costanti, ma alla fine potrebbero causare problemi:

if (Host_ip == '192.168.1.5'){
   printer = '192.168.1.123';
} else
  printer = 'prntrBob';

Un giorno Bob uscirà e la sua stampante verrà rinominata. Un giorno la stampante riceverà un nuovo indirizzo IP. Un giorno 192.168.1.5 vorranno stampare sulla stampante di Bob.

il mio mantra preferito: scrivere sempre il codice come uno psicopatico omicida che sappia dove vivi dovrai mantenerlo!

2
davidhaskins

Codice che mostra che il programmatore non si è mai adattato, anni fa, a Java 5:

  • Utilizzo di Iteratori anziché "per ciascuno"
  • Non usare generici nelle raccolte e trasmettere oggetti recuperati al tipo previsto
  • Utilizzando classi antiche come Vector e Hashtable

Non conoscendo i moderni modi multithread.

2
Dave Briccetti

Per SQL:

Il primo grande indicatore è l'uso di join impliciti.

Il prossimo è l'uso di un join sinistro su tableB combinato con una clausola WHERE come:

WHERE TableB.myField = 'test'

Se non sai che darà risultati errati, non posso fidarmi che qualsiasi query che scrivi darà risultati corretti.

2
HLGEM

Il nostro codice VB6 legacy, puoi aprire qualsiasi modulo o modulo pagina di codice e trovare una schermata piena di pubblico o globale # & @ ! variabili dichiarate in alto, referenziate da tutto il programma @ &! ! (*! #. ARGH !!!!

(Accidenti, ho dovuto tirarlo fuori :-))

2
HardCode

Qualcosa come questo

x.y.z.a[b].c

Questo puzza di bio-hazard. Questo riferimento ai membri non è mai un buon segno. E sì, questa è un'espressione tipica nel codice con cui sto lavorando.

2
Gaurav

qualcosa con qualcosa del genere

// TODO: anything could be here!

Modifica: dovrei qualificarmi nel codice di produzione. Ma anche nel codice impegnato nel controllo del codice sorgente questo non è ancora buono. Ma quella potrebbe essere una cosa personale in quanto mi piace finire la giornata dopo aver legato tutte le mie cose in sospeso :)

Modifica 2: dovrei qualificare ulteriormente ciò che intendevo quando vedo questo nel codice stabilito. Come qualcosa che ha diversi anni e sto risolvendo un bug. Vedo un TODO ed è allora che iniziano a suonare i campanelli d'allarme. TODO (per me) implica che il codice non è mai stato completato per qualche motivo.

2
Antony Scott

L'uso della parola chiave synchronized in Java.

Non che ci sia qualcosa di sbagliato nell'usare synchronized quando viene usato correttamente. Ma nel codice con cui lavoro, sembra che ogni volta che qualcuno prova a scrivere un codice thread-safe, si sbagliano. Quindi so che se vedo questa parola chiave, devo stare molto attento al resto del codice ...

1
Guillaume

Ottimizzazioni di spioncino su codice che potrebbero essere ottimizzate con una struttura migliore, ad es. ricerche lineari implementate in assembly inline quando una ricerca binaria in C/C++/Java/C # sarebbe appropriata (e più veloce).

O alla persona mancano alcuni concetti fondamentali o non ha senso delle priorità. Quest'ultimo è molto più preoccupante.

1
Rei Miyasaka

@FinnNk, sono d'accordo con te sul codice commentato. Ciò che mi dà veramente fastidio è roba del genere:

for (var i = 0; i < num; i++) {
    //alert(i);
}

o qualsiasi cosa fosse lì per il test o il debug e sia stata commentata e poi impegnata. Se è solo occasionale, non è un grosso problema, ma se è ovunque, ingombra il codice e rende difficile vedere cosa sta succedendo.

1
Elias Zamaria
  • $ data - È come pubblicizzare "Oggetti fisici, ora a un livello ridicolmente basso di 100 per 5!"
  • Articoli TODO nel codice: usa un tracker bug/ticket/issue in modo che le persone sappiano cosa è necessario a livello di prodotto piuttosto che a livello di file.
  • Codice di accesso al lavoro: ecco a cosa serve il controllo della versione.
1
l0b0

Tutto ciò che viola principi importanti. Ad esempio, sono stati suggeriti alcuni anti-pattern (numero magico - vedi http://en.wikipedia.org/wiki/Anti-pattern ). Gli anti-pattern sono chiamati così perché causano problemi (anche già menzionati: fragilità, incubi di manutenzione, ecc.). Inoltre, fai attenzione alla violazione di SOLID principi - vedi http://en.wikipedia.org/wiki/Solid_ (object-oriented_design) Inoltre, il codice che non prendere in considerazione la separazione dei livelli (elementi di accesso ai dati all'interno dell'interfaccia utente, ecc.) Avere standard di codifica e revisioni del codice aiuta a combattere questo.

1
Tim Claason

La maggior parte di questi provengono da Java:

  • Digitazione di stringhe. Solo ... no.
  • La tipografia indicherà spesso un odore di codice nella moderna Java.
  • L'anti-pattern di Pokemon Exception (quando devi prenderli tutti).
  • Tentativi di culto delle merci nella programmazione funzionale dove non è appropriato.
  • Non usare un costrutto di tipo funzionale (Callable, Function ecc.) Dove sarebbe appropriato.
  • Incapaci di sfruttare il polimorfismo.
1
Ben Hardy

Quando il codice sembra un disastro: commenti con "todo" e "note per se stessi" e battute pessime. Codice che è stato ovviamente utilizzato a un certo punto esclusivamente a scopo di debug, ma non è stato quindi rimosso. Variabili o funzioni con nomi che suggeriscono che lo scrittore non ha considerato che qualcuno lo avrebbe letto in seguito. Spesso questi nomi saranno molto lunghi e ingombranti.

Inoltre: se il codice non ha ritmo. Funzioni di lunghezza selvaggiamente divergenti. Funzioni che non aderiscono agli stessi schemi di denominazione.

Leggermente correlato: mi rende sempre nervoso se un programmatore ha una calligrafia sciatta. O se sono cattivi scrittori o cattivi comunicatori.

1
KaptajnKold

Una volta ho lavorato a un progetto in cui l'appaltatore aveva digitato tutti i tipi di dati standard da int a stringa, compresi i puntatori a nomi oscuri. Il suo approccio ha reso la comprensione del codice davvero difficile. Un altro stile che mi avverte è la flessibilità prematura; un prodotto su cui ho lavorato una volta aveva il codice completo nelle DLL che venivano caricate in un ordine non prevedibile. Tutto questo per accogliere l'evoluzione futura. Alcune DLL utilizzavano wrapper di thread per la portabilità. È stato un incubo eseguire il debug del programma o prevedere il flusso leggendo il codice sorgente. Le definizioni sono state sparse nei file di intestazione. Non è stata una sorpresa che il codice non sia sopravvissuto oltre la seconda versione.

1
VKs

A volte vedo parti di un metodo che ha dato tutti i possibili input, non funzionerebbe MAI, quindi non dovrebbe essere lì a confondere le persone in primo luogo. Un esempio sarebbe ...
Se il metodo può essere chiamato solo nel contesto di un superutente Admin e vedo qualcosa che controlla se l'utente della richiesta non è un superutente Admin ...: /

1
chiurox

Commenti scontenti che dimostrano la mancanza di moderazione:

//I CAN'T GET THIS F^#*&^ING PIECE OF S$^* TO COMPILE ON M$VC

O sono irascibili o non hanno abbastanza esperienza per aver imparato che le battute d'arresto sono inevitabili nella programmazione.

Non voglio lavorare con persone così.

1
Rei Miyasaka

Questo è un sintomo leggermente minore rispetto alle cose che altri hanno elencato, ma io sono un Python e spesso lo vedo nella nostra base di codice:

try:
    do_something()
except:
    pass

Il che di solito mi segnala che il programmatore non sapeva davvero (o che importava) perché do_something potrebbe non riuscire (o quello che fa) - ha appena continuato a "giocherellare" fino a quando il codice non si è bloccato più.


Per quelli che provengono da uno sfondo più simile a Java, quel blocco è l'equivalente di Python di

try {
    doSomething();
} catch (Exception e) {
    // Don't do anything. Don't even log the error.
}

Il fatto è che Python usa eccezioni per il codice "non eccezionale", come interruzioni di tastiera o interruzione di un ciclo for.

1
mipadi

chi va dappertutto mi fa impazzire.

e una cosa speciale: getter delegando ad altri getter.

questo è male perché significa che la persona che ha scritto che non capisce le basi dell'orientamento agli oggetti, che è l'incapsulamento, il che significa dove si trovano i dati, dovrebbero essere i metodi che agiscono su quei dati.

la delega è per un metodo non tutti i getter. il principio è "dillo, non chiedere"; dì una cosa a un oggetto da fare, non chiederlo per mille cose e poi fallo da solo.

mi fa impazzire, perché significa che altri principi di oop saranno violati dal nocciolo duro.

0
Belun

Informazioni sul tipo mancante.

Dai un'occhiata a queste firme dei metodi:

  1. public List<Invoice> GetInvoices(Customer c, Date d1, Date d2)

  2. public GetInvoices(c, d1, d2)

In (1) c'è chiarezza. Sai esattamente con quali parametri devi chiamare la funzione ed è chiaro cosa restituisce la funzione.

In (2) c'è solo incertezza. Non hai idea di quali parametri utilizzare e non sai cosa restituisce la funzione se qualcosa. Sei effettivamente costretto a utilizzare un approccio inefficace alla programmazione per tentativi ed errori.

0
ThomasX