"URL.hashCode"과 "URL.equals" 사용을 피하세요.

java.net.URL의 equals이나 hashCode 메서드는 hostname이나 IP 주소를 확인하기 위해, NameService(일반적으로 DNS)에 lookup 호출을 할 수도 있습니다. 따라서 네트워크 상태에 따라 시간이 오래 걸릴 수 있습니다. 반면 URI는 이러한 호출을 수행하지 않으므로, URL의 특정한 기능이 필요하지 않은 경우, 이를 대신 사용해야 합니다. 일반적으로 리소스에 실제로 접근할 필요가 하기 전까지는 URI 클래스를 사용하는 것이 좋습니다. URI를 URI.toURL()을 사용하여 URL로 변환할 수 있습니다. 이 규칙은 Map이나 Set에서 URL의 사용을 확인하고 있거나, eq...

더보기

중요한 파일 시스템 경로를 마운팅하는 것은 보안에 민감합니다.

중요한 파일 시스템 경로를 마운트하면 호스트 시스템의 정보가 노출되고 손상될 수 있습니다. 시스템 경로에는 구성 파일 또는 캐시 파일과 같은 중요한 정보가 포함될 수 있습니다. 공격자가 사용 권한을 확장하거나 추가 공격을 위한 정보를 수집하는 데 사용할 수 있습니다. 또한, 시스템 경로에는 호스트 시스템에서 주기적으로 실행할 수 있는 바이너리 및 스크립트도 포함될 수 있습니다. 중요한 파일에 액세스할 수 있는 손상되거나 악성 컨테이너는 전체 Kubernetes 클러스터의 무결성을 위험하게 만들 수 있습니다. 다음 질문을 확인하세요 마운트된 파일 경로가 중요한 정보를 포함하고 있다. 마운트된 파일 경로...

더보기

Primitive 배열에는 "Arrays.stream"이 사용되어야 합니다

String::replaceAll의 기본 구현은 java.util.regex.Pattern.compile()을 매번 호출하도록 되어있습니다. (첫번째 인수 값이 정규표현이 아닌 경우에도) 이는 굉장히 큰 성능 문제를 야기하기 때문에, 사용에 매우 주의해야합니다. String::replaceAll을 사용하는 경우라면, 첫 번째 인수는 실제 정규식이어야 합니다. 그렇지 않다면, String::replace이 정규식으로 인한 성능 저하 없이 String::replaceAll과 정확히 동일한 작업을 수행하니 이를 사용하는 것이 좋습니다. 이 규칙은 각 String::replaceAll의 첫 번째 인수가 특수 정규식 문...

더보기

"read(byte[],int,int)"은 오버라이딩 되어야 합니다

java.io.InputStream나 java.io.FilterInputStream을 직접 서브 클래스로 만드려 할 때, 요구하는 스펙은 read()만 재정의하면 됩니다. 하지만 실제로는 read(byte[],int,int) 메소드도 구현할 필요가 있습니다. 왜냐면 Stream의 특성상 바이트를 하나하나 읽는 경우보다 여러 read(byte[],int,int)을 이용하여 여러 바이트를 동시에 읽어오는 경우가 많기 때문입니다. read()으로 하나하나 읽어오게 되면 굉장히 비효율적이고 오버헤드가 많이 발생할겁니다. 따라서 서브 클래스에서 read(byte[],int,int)에 효율적인 구현을 만들어 두는 것이 좋습니...

더보기

"Preconditions"과 로깅 매개변수에는 evaluation(계산식)을 사용하지 않습니다.

Guava에 있는 com.google.common.base.Preconditions같은 코드에 evaluation(계산식)을 사용하는 것이 성능 저하를 만들 수 있습니다. 왜냐하면 계산이 실제로 필요하든 아니든, 메소드 호출을 하기 위해, 매개변수 값을 얻기 위하여 계산식이 항상 실행되기 때문입니다. 마찬가지로 문자열 concatenated 연산을 포함한 매개변수를 로깅 메소드로 넘겨주게되면, log level에 관계없이 문자열 concat 연산이 발생해 성능 저하를 만들 수 있습니다. 계산식 대신 정적인 값이나 사전에 계산이 완료된 값만을 Preconditions와 log 호출에 사용해야합니다. 특히 문자열...

더보기

"ResultSet.isLast()"은 사용하지 않는 것이 좋습니다.

ResultSet.isLast()를 사용하지 않으면 좋은 데에는 여러 이유가 있습니다. 첫째로 이 메소드는 TYPE_FORWARD_ONLY ResultSet인 경우 optional하게 지원됩니다. 둘째로 이 메소드는 매우 비싼 연산입니다. (이 메소드를 처리하기 위해 드라이버가 next row를 가져와야 할 수 있습니다) 마지막으로 ResultSet이 비어있는 경우 어떤 결과를 반환해야하는지가 명확하지 않습니다. 그래서 어떤 드라이버에서는 기대한 것과는 다른 결과를 반환하기도 합니다. 규칙을 어긴 코드 stmt.executeQuery("SELECT name, address FROM PERSON"); Result...

더보기

"finalize"에서는 필드 값을 null로 변경해선 안됩니다.

finalize에서 클래스 필드를 null로 설정하는 것은 아무런 의미가 없습니다. 혹시 garbage collector에게 힌트를 주기 위해서 이런 코드를 작성했다면, 더더욱 불필요합니다. garbage collector는 알아서 잘 동작할 것이고, 오히려 garbage collector에 추가 작업이 발생할 수도 있습니다. 규칙을 어긴 코드 public class Foo { private String name; @Override void finalize() { name = null; // 규칙을 어긴 코드; 완전 필요 없는 코드 } } If you like SONARKUBE,...

더보기

Primitive 배열에는 "Arrays.stream"이 사용되어야 합니다

객체의 배열을 처리하기 위해 사용되는 Arrays.asList(T ... a).stream()과 Arrays.stream(array)은 기본적으로 같은 성능을 보입니다. 하지만, Primitives(기본 자료형) 배열에 사용되는 경우 Arrays.asList을 사용하게 되면, boxed types(객체형)의 리스트 생성자를 강제하게 되고 이를 stream에 사용합니다. 반면 Arrays.stream은 기본 자료형에 대응되는 적절한 stream 타입(IntStream, LongStream, DoubleStream)을 골라 사용하게 됩니다. 그리고 이 덕분에 더 나은 성능을 얻을 수 있게 됩니다. 규칙을 어긴 코드 ...

더보기