Códigos de baixa qualidade levam a comportamentos imprevisíveis. Da perspectiva do usuário, isso normalmente se manifesta como usabilidade ruim. Para um invasor, trata-se de uma oportunidade para atacar o sistema de formas imprevistas.
void clean_up()
{
char tmp[256];
...
free(tmp);
return;
}
System.Object.Equals()
:
public boolean Equals(string obj) {
...
}
System.Object.Equals()
usa um argumento do tipo object
, o método nunca é chamado.Object.equals()
:
public boolean equals(Object obj1, Object obj2) {
...
}
Object.equals()
usa apenas um argumento, o método no Example 1
nunca é chamado.ISerializable
, mas não declararem o atributo [Serializable]
, não serão serializadas.[Serializable]
. Se a classe puder ser serializada usando os métodos de serialização padrão definidos pelo .NET Framework, será necessário e suficiente que o objeto seja serializado corretamente. Se a classe exigir métodos de serialização personalizados, ela também deverá implementar a interface ISerializable
. No entanto, a classe ainda deve declarar o atributo [Serializable]
.CustomStorage
implementa a interface ISerializable
. No entanto, por não declarar o atributo [Serializable]
, ela não será serializada.
public class CustomStorage: ISerializable {
...
}
java.io.Serializable
podem causar problemas e deixar vazar informações da classe externa.
...
class User implements Serializable {
private int accessLevel;
class Registrator implements Serializable {
...
}
}
Example 1
, quando a classe interna Registrator
for serializada, ela também serializará o campo accessLevel
da classe externa User
.synchronized
, garantindo o comportamento correto quando vários threads acessam a mesma instância. Todos os métodos de substituição também devem ser declarados como synchronized
, caso contrário, um comportamento inesperado poderá ocorrer.Foo
substitui a classe Bar
, mas não declara o método synchronizedMethod
como synchronized
:
public class Bar {
public synchronized void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
public class Foo extends Bar {
public void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
Foo
pode ser convertida no tipo Bar
. Se a mesma instância for fornecida a dois threads separados e synchronizedMethod
for executado repetidamente, o comportamento será imprevisível.obj.Equals(null)
sempre deve ser "false".Equals()
para comparar um objeto com null
. O contrato do método Equals()
exige que essa comparação sempre retorne "false".obj.equals(null)
sempre será "false".equals()
para comparar um objeto com null
. Essa comparação sempre retornará "false", uma vez que o objeto não é null
. (Se o objeto for null
, o programa lançará NullPointerException
).pthread_create()
a partir da função main()
do processo pai serão encerrados prematuramente se o processo pai encerrar sua execução antes dos threads que ele gerou, sem chamar pthread_exit()
. Chamar pthread_exit()
garante que o processo pai permanecerá ativo até que a execução de todos os seus threads tenha sido encerrada. Como alternativa, o processo pai pode chamar pthread_join
em todos os threads filho e garantir que eles serão concluídos antes da conclusão do processo.pthread_create()
para criar um thread e depois é encerrado normalmente. Se a conclusão do thread filho não tiver sido encerrada até o retorno da função main()
, o thread será encerrado prematuramente.
void *Simple(void *threadid)
{
...
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int rc;
pthread_t pt;
rc = pthread_create(&pt, NULL, Simple, (void *)t);
if (rc){
exit(-1);
}
}