코드 품질이 낮으면 예측할 수 없는 동작이 발생합니다. 사용자 입장에서는 사용 편의성이 떨어지는 것으로 나타나는 경우가 많습니다. 공격자에게는 예상치 못한 방법으로 시스템에 부담을 줄 수 있는 기회가 됩니다.
void clean_up()
{
char tmp[256];
...
free(tmp);
return;
}
System.Object.Equals()
를 오버라이드합니다.
public boolean Equals(string obj) {
...
}
System.Object.Equals()
가 object
유형의 인수를 받기 때문에 해당 메서드는 호출되지 않습니다.Object.equals()
를 오버라이드합니다.
public boolean equals(Object obj1, Object obj2) {
...
}
Object.equals()
가 하나의 인수만 받기 때문에 Example 1
의 메서드는 호출되지 않습니다.ISerializable
인터페이스를 구현하지만 [Serializable]
속성을 선언하지 않는 클래스는 직렬화되지 않습니다.[Serializable]
속성을 선언하는 모든 개체의 serialization을 허용합니다. .NET 프레임워크에 의해 정의된 기본 serialization 메서드를 사용하여 클래스를 직렬화할 수 있으면 개체를 정확하게 직렬화해야 할 필요와 직렬화하기 위한 충분한 조건이 충족됩니다. 클래스가 사용자 지정 serialization 메서드를 사용해야 하는 경우 ISerializable
인터페이스도 구현해야 합니다. 그러나, 이 경우에도 클래스는 [Serializable]
속성을 선언해야 합니다.CustomStorage
클래스는 ISerializable
인터페이스를 구현합니다. 그러나, [Serializable]
속성의 선언이 실패하므로 직렬화되지 않습니다.
public class CustomStorage: ISerializable {
...
}
java.io.Serializable
을 구현하는 inner class를 사용하면 outer class에서 문제가 발생하고 정보가 누출될 수 있습니다.
...
class User implements Serializable {
private int accessLevel;
class Registrator implements Serializable {
...
}
}
Example 1
에서 inner class Registrator
를 serialize하면 outer class User
의 accessLevel
필드도 serialize됩니다.synchronized
메서드를 선언했고 여러 스레드가 동일한 인스턴스에 접근할 때 올바른 동작을 보장합니다. 또한 모든 오버라이드 메서드는 synchronized
로 선언되어야 합니다. 그렇지 않으면 예기치 못한 동작이 발생할 수도 있습니다.Foo
클래스는 Bar
클래스를 오버라이드하지만 synchronizedMethod
메서드를 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
의 인스턴스가 Bar
유형으로 배정될 수 있습니다. 같은 인스턴스를 서로 다른 두 스레드에 지정하고 synchronizedMethod
를 반복 실행하면 동작을 예측할 수 없게 됩니다.obj.Equals(null)
는 항상 false가 됩니다.Equals()
메서드를 사용하여 개체를 null
과 비교합니다. Equals()
메서드의 약정이 항상 false로 반환되도록 비교해야 합니다.obj.equals(null)
는 항상 false가 됩니다.equals()
메서드를 사용하여 개체를 null
과 비교합니다. 이 비교는 개체가 null
이 아니기 때문에 항상 false를 반환합니다. (개체가 null
이면 프로그램에 NullPointerException
이 발생합니다).main()
함수에서 pthread_create()
를 호출하여 생성된 스레드는 해당 스레드가 pthread_exit()
을 호출하기 전에 상위 프로세스의 실행이 완료되면 비정상적으로 조기 종료됩니다. pthread_exit()
를 호출하면 상위 프로세스가 모든 해당 스레드의 실행이 완료될 때까지 그대로 유지됩니다. 또는 상위 프로세스가 모든 하위 스레드에서 pthread_join
을 호출할 수 있으며 프로세스가 끝나기 전에 완료할 수 있도록 합니다.pthread_create()
를 사용하여 스레드를 생성하고 정상적으로 종료되도록 합니다. 하위 스레드가 main()
함수가 반환될 때 까지 해당 실행을 완료하지 않는 경우, 비정상적인 조기 종료가 발생합니다.
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);
}
}