728x90

path:

/opt/homebrew/Cellar/tomcat@9/9.0.65/libexec


내저장소 바로가기 luxury515

728x90

갑자기 후임이 “IPv6가 뭐고 , IPv4와 비교하면 어떤 장점” 있나요? 질문은 한다.

순간 생각나는 대로 대답해줬는데 뭔가 이해가 안된 표정.

그래서 나름대로 찾아서 정리해 보았다.

ipv6 를 출시하게 된 배경.

기존 ipv4는 32bit로 식별되며 이론적으로 제공할 수 있는 주소의 수는 약 43억 개라고 한다. (이렇게 많은데도 부족하다니… ㅜ.ㅜ )

또한 IPv4 주소의 할당도 불균등하여 미국은 전 세계 주소 공간의 약 절반을 차지하며 유럽은 상대적으로 부족하고 아시아 태평양 지역은 더욱 부족하다고 한다.

그리고 최근 모바일 IP와 광대역 기술의 발전은 더 많은 IP 주소를 필요로 한다. 현재 IPv4 주소가 소진되었다고 한다. IPv4 주소 부족에 대한 몇 가지 해결 방법이 등장하기도 했다.

CIDR과 NAT이 대표적이다.그러나 CIDR과 NAT은 각각의 단점과 해결할 수 없는 문제를 가지고 있어 IPv6의 발전에 가속페달을 밟게 함.

IPv6 주소는 128bit로 식별되는데 128bit의 주소 공간을 통해 IPv6는 이론적으로 약(43억 x 43억 x 43억 x 43억)개의 주소를 가질 수 있다고 한다. 거의 무한에 가까운 주소 공간인데… 그럼 128 아닌256 512도 나오는거 아님? ^^ 우리같은 빡대가리들은 그냥 출시되면 그대로 쓰면 될것 같다!!!.

메시지 처리 측면에서 IPv4 헤더에는 Security, Timestamp, Record Route 등과 관련된 Options(옵션 필드)가 포함되어 있다. 이러한 Options는 IPv4 헤더의 길이를 20 Byte에서 60 Byte로 확장할 수 있다. 이러한 Options를 운반하는 IPv4 메시지를 전달하려면 소프트웨어로 중간 경로 전달 장치를 처리해야 하는 경우가 많으므로 성능 오버헤드가 크므로 실제로 거의 사용되지 않는다.

IPv6는 IPv4에 비해 메시지 헤더는 Internet Header Length, Identifier, Flag, Fragment Offset, Header Checksum, Options 및 Padding 필드를 제거하고 스트림 태그 필드만 추가하므로 IPv6은 IPv4에 비해 메시지 헤더를 훨씬 더 쉽게 처리하고 처리 효율성을 향상시킨다. 또한 IPv6는 다양한 옵션의 처리를 보다 잘 지원하기 위해 확장된 헤더의 개념을 제시하였으며, 새로운 옵션의 경우 IPv6 헤더의 구조를 수정할 필요가 없으며 이론적으로 무한히 다양한 옵션을 확장할 수 있어 뛰어난 확장성을 구현하였다.

주소 유지보수의 경우 IPv4 주소가 32bit에 불과하고 주소 할당이 불균형하여 네트워크 용량 확장 또는 재배포 시 IP 주소를 재할당해야 하는 경우가 많으므로 유지 보수 작업량을 줄이기 위해 IP 주소를 자동으로 구성하고 재주소할 수 있는 메커니즘이 필요함.현재 IPv4의 자동 구성 및 재코딩 메커니즘은 주로 DHCP에 의존함. IPv6 프로토콜은 자동 주소 설정을 통해 호스트가 네트워크를 자동으로 검색하고 IPv6 주소를 얻을 수 있는 메커니즘을 내장하여 내부 네트워크의 관리성을 크게 향상시킴.

라우팅 집약의 경우 IPv4 개발 초기 주소 할당 계획 문제로 인해 할당된 많은 IPv4 주소가 불연속적이어서 라우팅을 효율적으로 집약할 수 없음.점점 더 많은 양의 라우팅 테이블은 많은 메모리를 소비하여 장비 용량과 전송 효율에 영향을 미치므로 장비 제조업체는 라우팅 주소 지정 및 전송 성능을 향상시키기 위해 제품을 지속적으로 업그레이드해야 한다. IPv6의 거대한 주소 공간은 IPv6가 계층화된 네트워크를 쉽게 배치할 수 있도록 한다.계층화된 네트워크 구조는 라우팅 집합을 보다 쉽게 만들고 라우팅 및 전달의 효율성을 향상시킨다.

엔드 투 엔드 보안의 경우 IPv4 프로토콜을 개발할 때 보안에 대한 시스템 설계가 부족하여 고유한 프레임워크 구조가 엔드 투 엔드 보안을 지원하지 않는다. IPv6에서 네트워크 계층은 IPsec의 인증 및 암호화를 지원하며 엔드 투 엔드 보안을 지원한다.

QoS 보장 측면에서 인터넷 회의, 인터넷 전화, 인터넷 TV의 급속한 대중화와 사용으로 고객은 오디오 및 비디오 업무의 실시간 전송을 보장하기 위해 더 나은 QoS를 요구하지만 IPv4는 QoS를 보장할 특별한 수단이 없습니다. IPv6에는 QoS 보장에 사용할 수 있는 스트림 태그 필드가 추가되었다.

이동성 지원 측면에서 모바일 IPv4에는 삼각 라우팅, 소스 주소 필터링 등과 같은 몇 가지 문제가 있다. IPv6 프로토콜은 이동성을 지원해야 한다고 규정하고 있다.모바일 IPv4에 비해 모바일 IPv6는 외부 에이전트를 사용하지 않고 외부 네트워크를 직접 검색하고 주소를 전달할 수 있다.동시에 라우팅 확장 메시지 헤더와 목적 옵션을 사용하여 메시지 헤더를 확장하면 모바일 노드와 피어 노드 간에 직접 통신할 수 있으며 모바일 IPv4 삼각 라우팅 및 소스 주소 필터링 문제를 해결하여 이동통신 처리 효율을 높이고 애플리케이션 계층을 투명하게 한다.


내저장소 바로가기 luxury515

728x90

들어가면서

Java에서 모든 객체는 기본적으로 Object 클래스를 상속하며, Object 클래스에는 equals()와 hashCode() 메서드가 정의되어 있습니다.

차이점

equals() 메서드는 객체의 동등성을 비교하고, hashCode() 메서드는 객체를 해시 테이블 등에 저장할 때 사용됩니다.

객체의 equals() 메서드를 오버라이딩하면, 두 객체의 동등성을 비교할 때 더욱 정확한 결과를 얻을 수 있습니다. equals() 메서드를 오버라이딩하지 않으면, 두 객체가 동일한 인스턴스인지만 비교하게 됩니다. 예를 들어, String 클래스의 경우, 문자열의 값이 같으면 두 String 객체는 동등한 것으로 간주됩니다. 하지만 String 객체의 equals() 메서드를 오버라이딩하지 않으면, 두 String 객체가 동등한지 여부를 확인하는 것이 불가능합니다.

hashCode() 메서드는 객체를 해시 테이블 등에 저장할 때 사용됩니다. 만약 두 객체가 equals() 메서드를 통해 동등하다면, 두 객체의 hashCode() 값도 동일해야 합니다. hashCode() 메서드를 오버라이딩하지 않으면, 객체의 메모리 주소를 기반으로 해시 코드가 생성됩니다. 하지만 같은 객체라도 프로그램의 실행 상황에 따라 메모리 주소가 달라질 수 있으므로, 이러한 방식으로 해시 코드를 생성하면 문제가 발생할 수 있습니다.

따라서, equals() 메서드와 hashCode() 메서드를 오버라이딩하여 객체의 동등성 비교와 해시 코드 생성을 정확하게 구현해야 합니다.

@equals와 @hashCode는 자바 어노테이션으로, 해당 메서드를 오버라이딩하겠다는 것을 나타냅니다. 이 어노테이션을 사용하면 개발자가 실수로 메서드를 오버라이딩하지 않는 경우를 방지할 수 있습니다.

객체의 equals() 메서드와 hashCode() 메서드를 오버라이딩하는 방법을 예시 코드로 보여드리겠습니다.

다음은 Student 클래스를 예시로 들어보겠습니다.

public class Student {
    private String name;
    private int age;
    private int studentId;

    // 생성자와 getter/setter 메서드는 생략

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof Student)) return false;
        Student student = (Student) obj;
        return student.studentId == this.studentId;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + studentId;
        return result;
    }
}

위 코드에서 equals() 메서드는 학생의 학번(studentId)을 비교하여 두 객체가 동등한지 여부를 판단하도록 구현되었습니다. 또한, hashCode() 메서드는 학번(studentId) 값을 사용하여 해시 코드를 생성하도록 구현되었습니다.

만약 equals() 메서드와 hashCode() 메서드를 오버라이딩하지 않았다면, 두 학생 객체가 동등한지 여부를 확인하는 것이 불가능했을 것입니다.

Student student1 = new Student("John", 20, 1001);
Student student2 = new Student("Alice", 22, 1001);
boolean isEqual = student1.equals(student2); // true

위 코드에서 student1과 student2는 이름과 나이는 다르지만 학번이 동일합니다. 따라서 equals() 메서드를 오버라이딩하여 학번이 같은 경우 동등하다는 것을 정의하면, 두 객체가 동등하다고 판단됩니다.

hashCode() 메서드를 오버라이딩하지 않으면, 객체의 메모리 주소를 기반으로 해시 코드가 생성됩니다. 하지만 같은 객체라도 프로그램의 실행 상황에 따라 메모리 주소가 달라질 수 있으므로, 이러한 방식으로 해시 코드를 생성하면 문제가 발생할 수 있습니다. 따라서 hashCode() 메서드를 오버라이딩하여 학번(studentId) 값을 사용하여 해시 코드를 생성하도록 구현합니다.

Map<Student, String> map = new HashMap<>();
map.put(student1, "John");
map.put(student2, "Alice");
System.out.println(map.get(student1)); // John
System.out.println(map.get(student2)); // Alice

위 코드에서는 HashMap을 사용하여 학생 객체와 문자열 데이터를 저장하였습니다. HashMap은 객체의 해시 코드를 기반으로 데이터를 저장하므로, hashCode() 메서드를 오버라이딩하여 해시 코드를 정확하게 생성하는 것이 중요합니다. 따라서 위 코드에서는 학번(studentId)을 사용하여 해시 코드를 생성하도록 구현하였습니다.

결론적으로…

equals()와 hashCode() 메서드를 오버라이딩하여 객체의 동등성 비교와 해시 코드 생성을 정확하게 구현해야 합니다. @equals와 @hashCode 어노테이션을 사용하면 오버라이딩을 보다 쉽게 구현할 수 있습니다.


내저장소 바로가기 luxury515

728x90

ispresent vs ifpresent 의 차이점

Optional<OrderDto> optionalOrderDto = queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOneOptional();

if (optionalOrderDto.isPresent()) {
    OrderDto orderDto = optionalOrderDto.get();

    List<OrderItemDto> orderItemDtos = queryFactory
        .select(Projections.constructor(OrderItemDto.class, item))
        .from(orderItem)
        .join(orderItem.item, item)
        .where(orderItem.order.id.eq(orderId))
        .fetch();

    orderDto.setOrderItemDtos(orderItemDtos);

    return orderDto;
} else {
    throw new NotFoundException("Order not found");
}

위 코드에서는 isPresent() 메서드를 사용하여 Optional 객체가 null인지 체크하고, get() 메서드를 사용하여 OrderDto 객체를 가져옵니다. OrderDto 객체가 null이 아니면 해당 객체를 사용하여 쿼리를 실행하고, null이면 NotFoundException 예외를 발생시킵니다.

반면에 ifPresent()를 사용하면 다음과 같이 null 체크와 쿼리 실행을 한 번에 할 수 있습니다.

queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOneOptional()
        .ifPresent(orderDto -> {
            List<OrderItemDto> orderItemDtos = queryFactory
                    .select(Projections.constructor(OrderItemDto.class, item))
                    .from(orderItem)
                    .join(orderItem.item, item)
                    .where(orderItem.order.id.eq(orderId))
                    .fetch();

            orderDto.setOrderItemDtos(orderItemDtos);
        })
        .orElseThrow(() -> new NotFoundException("Order not found"));

위 코드에서는 ifPresent() 메서드를 사용하여 Optional 객체가 null이 아닐 때만 람다식을 실행하고, orElseThrow() 메서드를 사용하여 NotFoundException 예외를 발생시킵니다.

isPresent()ifPresent() 모두 null 체크를 수행하지만, ifPresent()는 null 체크와 쿼리 실행을 한 번에 처리할 수 있습니다. 그러나 ifPresent()는 리턴값을 갖지 않기 때문에, 리턴값을 사용해야 하는 경우에는 isPresent()get() 메서드를 사용해야 합니다.


내저장소 바로가기 luxury515

+ Recent posts