안녕하세요!

자바의 컬렉션 3탄! 오늘은 Set에 대해서 알아보겠습니다.

 

오늘은 아래 Map 컬렉션 내용을 보지 않으셨다면 보시는걸 추천드립니다.

아니다. 꼭 보세요! 내용이 상당히 비슷합니다.

https://nnmmyy.tistory.com/55

 

[자바] 컬렉션(Collection) 2 - Map

안녕하세요!자바의 컬렉션 2탄! 오늘은 Map에 대해서 알아보겠습니다. 자료구조? 컬렉션?컬렉션을 알아보기 전에 자료구조라는 단어를 들어보셨을 텐데요 이는 프로그래밍 과정에서 데이터를

nnmmyy.tistory.com

 

 

자료구조? 컬렉션?


컬렉션을 알아보기 전에 자료구조라는 단어를 들어보셨을 텐데요 이는 프로그래밍 과정에서 데이터를 효율적으로 사용하기 위해 만들어진 것으로 배열, 리스트, 스택 등이 있습니다. 이 자료구조들을 사용하려 할 때 우리가 직접 구현해서 사용하기는 어렵고 귀찮기 때문에 자바에서 이 자료구조들을 구현하고 인터페이스화 시켜 개발자들이 사용할 수 있도록 제공하는 프레임워크를 컬렉션 이라고 합니다.

 

Set

Set은 중복을 허용하지 않는 것이 특징인 자료구조 입니다. 기본적으로 순서를 보장하지 않습니다.

 

HashSet


HashSet은 해시 테이블을 기반으로 한 Set의 구현체 입니다. 또한 내부적으로는 HashMap을 사용하는데요 HashMap의 특징과 완전히 똑같은데 HashMap의 특징은 키의 중복을 허용하지 않습니다. 바로 이 특징이 HashSet에 이용되는데요 

HashMap의 키에 HashSet의 Value값을 저장하고 값으로는 더미 객체를 사용하게 됩니다. 그래서 set이 중복을 허용하지 않는 자료구조가 되는것이죠

 

LinkedHashSet


자 그러면 눈치채셨나요? LinkedHashSet은 LinkedHashMap을 사용해서 구현하는 겁니다. LinkedHashMap과 같은 특징을 가지고 있으면서 set처럼 동작하는것이죠. Set 구현체 중에서 삽입순서를 유지하는것이 특징입니다.

 

TreeSet


TreeSet또한 같습니다. TreeMap을 통해 구현하게 되며 값으로 오름차순 정렬되는것이 특징입니다.

 

오늘은 Set에 관련해서 알아보는 시간이었는데요

Map 컬렉션을 보고오셨다면 사실 Set은 거의 날로먹는거네요!

감사합니다.

안녕하세요!

자바의 컬렉션 2탄! 오늘은 Map에 대해서 알아보겠습니다.

 

자료구조? 컬렉션?


컬렉션을 알아보기 전에 자료구조라는 단어를 들어보셨을 텐데요 이는 프로그래밍 과정에서 데이터를 효율적으로 사용하기 위해 만들어진 것으로 배열, 리스트, 스택 등이 있습니다. 이 자료구조들을 사용하려 할 때 우리가 직접 구현해서 사용하기는 어렵고 귀찮기 때문에 자바에서 이 자료구조들을 구현하고 인터페이스화 시켜 개발자들이 사용할 수 있도록 제공하는 프레임워크를 컬렉션 이라고 합니다.

 

Map

Map은 키-값의 쌍으로 데이터를 저장하고 관리하는 자료구조입니다. 기본적으로 값의 순서를 유지하지 않으며 키의 중복값은 허용하지 않으나 값은 중복될 수 있습니다.

 

HashMap


HashMap은 해시 테이블을 기반으로 한 Map 구현체 입니다. HashMap은 배열, 연결 리스트, 트리의 혼합 구조로 이루어져 있습니다. 기본적으로는 해쉬코드를 통해 배열에 키-값 버킷을 저장하여 참조하게 되는데 해쉬 충돌이 발생할 경우 연결리스트로 버킷들을 관리하게 됩니다. 이후 연결리스트가 특정 크기를 넘어설 때 트리 형태로 변환되어 동작하게 됩니다.

 

장점

1. 빠른 데이터 접근이 가능하다

 - 키를 통해 1:1 매칭되는 값을 가지고 있기에 빠른 데이터 검색이 가능합니다.

 

단점

1. 순서를 보장하지 않는다.

 - 저장하는 순서를 관리하지 않습니다.

2. 해시 충돌이 발생할 수 있다.

 - 해시코드의 특성 상 해쉬 충돌이 발생할 경우 성능이 저하될 수 있다.

 

HashMap은 데이터의 순서에 상관없이 빠르게 검색이나 데이터를 저장할 경우 사용하는 것이 좋습니다.

 

LinkedHashMap


LinkedHashMap은 HashMap을 상속한 클래스 인데요 HashMap과 거의 동일하지만 데이터의 입력순서를 보장한다는것이 특징입니다. 이중 연결 리스트로 만들어져 내부 노드에 앞, 뒤 노드의 위치값을 참조하는 형태로 입력 순서를 유지할 수 있습니다.

 

HashMap보다는 약간 느리지만 입력 순서를 보장해야할 경우 사용할 수 있습니다.

 

TreeMap


TreeMap은 이름에서도 알 수있듯 Tree를 기반으로 만들어진 Map입니다. TreeMap의 주요 특징은 키를 기준으로 오름차순 정렬되어 저장한다는 것입니다.

 

장점

1. 정렬이 가능하다.

 - 키를 기준으로 오름차순 또는 사용자 지정 순서로 정렬이 가능합니다.

 

단점

1. 성능

 - Hash함수를 이용하는 Map에 비해 비교적 느린 성능을 보입니다.

 

내부구조

TreeMap에서 Tree는 이진 탐색 트리 기반의 레드-블랙 트리를 사용하는데요 노드에 키-값 쌍을 저장하는 형태입니다.

 

이진탐색트리

먼저 이진 탐색 트리는 각 노드가 최대 2개의 자식노드를 가지는 '이진 트리'와 데이터를 정렬된 순서로 유지하는 '탐색 트리'로서 데이터를 효율적으로 저장,검색,삽입,삭제 할 수 있습니다.

레드-블랙 트리

이진 탐색 트리의 일종이며 각 노드가 빨강 혹은 검정으로 색칠되어 레드-블랙 트리로 불립니다. 항상 균형을 유지하는 균형 트리로서 O(log n)의 시간복잡도를 보장함

 

Hashtable


 

Hashtable은 이름 그대로 해시 테이블을 기반으로 한 Map의 구현체인데요 스레드 안전(동기화)을 지원하는 것이 특징입니다. Hashtable도 HashMap과 비슷한 동작을 하지만 멀티스레드 환경에서의 안전성을 위해 스레드 안전을 지원합니다.


ConcurrentHashMap


ConcurrentHashMap은 Hashtable과 같이 스레드 안전을 지원하는 Map의 구현체입니다. 다만 성능적으로 더 우수한 Map인데요 메서드 전체에 락이 걸려있는 Hashtable에 비해 버킷 수준의 락을 통해 성능적으로 우수하며 해시충돌이 발생했을 때 연결리스트로 변환되는 Hashtable에 비해 리스트가 커졌을 때 Tree형태로 변환하여 성능적으로 우수합니다.

 

오늘은 자바 컬렉션중 Map과 구현체들에 대해 알아봤습니다.

감사합니다!

안녕하세요!

오늘은 데이터베이스의 검색 방법중 JOIN에 대해서 자세히 알아보겠습니다.

 

조인


조인은 데이터베이스에서 여러 테이블에 저장된 데이터를 연결하거나 결합해서 조회할 때 사용하는 SQL의 기능 입니다.

각 테이블의 특정 관계 (PK, 외래 키)를 통해 연결하여 데이터를 합칠 수 있습니다.

 

조인의 종류


  • INNER JOIN
  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN
  • CROSS JOIN
  • SELF JOIN

 

INNER JOIN

 

SELECT A.id, B.name FROM 기준테이블 A
INNER JOIN 조인테이블 B
ON A.id = B.id;


두 비교 대상 A,B 테이블에서 지정한 ON 구문의 필드값이 공통으로 중복된 값, 즉 교집합에 해당하는 값을 가져옵니다. 두 테이블 간에 매칭되지 않은 행은 검색 결과에서 제외됩니다.

가장 기본적인 조인으로서 INNER JOIN 대신 JOIN만 작성해도 INNER JOIN이 적용됩니다.

LEFT OUTER JOIN

SELECT A.id, B.name FROM 기준테이블 A
LEFT OUTER JOIN 조인테이블 B
ON A.id = B.id;

기준테이블 A의 모든 데이터의 값과 연결로 지정된 필드가 공통으로 중복된 값에 해당하는 결과값을 보여줍니다.

이때 기준테이블의 모든 행을 반환하고 조인 테이블에 매칭되지 않는 값들은 NULL로 채워집니다.

LEFT JOIN으로 구문을 작성해도 LEFT OUTER JOIN이 적용됩니다.

위 처럼 기준테이블에만 존재하는 값을 가져오고자 할때는 조건문을 통해 구현이 가능합니다.

SELECT A.id FROM 기준테이블 A
LEFT OUTER JOIN 조인테이블 B
ON A.id = B.id
WHERE B.id IS NULL;

이렇게 조건을 넣어주면 기준테이블과 조인테이블이 매칭되지 않은 기준테이블 A 의 값들에 대해서만 조회가 가능합니다.

RIGHT OUTER JOIN

LEFT OUTER JOIN과 내용은 동일하기 때문에 넘어가지만

RIGHT JOIN은 기준테이블의 값을 가져오는게 아닌 조인테이블의 값을 베이스로 가져오게 됩니다.

FULL OUTER JOIN

SELECT A.id, B.name FROM 기준테이블 A
FULL OUTER JOIN 조인테이블 B
ON A.id = B.id;

두 테이블의 모든 데이터를 결과값으로 가져옵니다.

다만 상호 매칭되지 않은 값에 대해서는 NULL로 채워집니다.

FULL JOIN으로 구문을 실행해도 FULL OUTER JOIN으로 적용됩니다.

CROSS JOIN

SELECT A.id, B.name FROM 기준테이블 A
CROSS JOIN 조인테이블 B

크로스 조인은 A,B 두 집합의 각요소를 조합하여 모든 가능한 쌍을 만드는 카테시안 곱으로도 불리는 조인입니다.

 

조인하려는 두 테이블의 모든 경우의수를 생성하도록 동작하여 N x M개의 결과값을 반환합니다.

SELF JOIN

SELF JOIN은 말 그대로 자기 자신 테이블과 조인하는 것인데요 같은 테이블의 행들간의 관계를 나타내는데 주로 사용합니다.

직원 테이블
id name manager
1 김영하 null
2 아몬드 1
3 허재 1
4 김상식 2
5 조용필 2

위와 같은 형태의 테이블이 있을 때 사원들의 관리자는 id 코드로 관리되어 있어 명확히 찾기가 어렵습니다.

SELECT e.name AS name, m.name AS manager
FROM employee e
LEFT JOIN employee m
ON e.manager_id = m.id;

SELF JOIN은 다른 키워드는 없이 JOIN문을 자신의 테이블에 거는것을 이야기 하는데요 위 처럼 SQL을 통해 사원별 관리자 이름을 확인하고자 했고 LEFT JOIN을 통해 관리자가 없는 직원의 경우는 null 값으로 표기하도록 했습니다.

[SQL결과]

name manager
김영하 null
아몬드 김영하
허재 김영하
김상식 아몬드
조용필 아몬드

이렇게 셀프 조인을 통해 같은 테이블 간에 정보를 확실하게 확인할 수 있겠네요

USING VS ON

두 테이블을 조인할 때 조인 조건 지정방법으로 USING과 ON이 사용 가능합니다.

USING절은 비교하려는 테이블에서 열의 이름이 동일할 경우에만 사용이 가능하며 결과집합에서 중복이 제거되어 하나의 컬럼으로 나타납니다.

 

반면 ON의 경우 두 테이블의 열 이름이 달라도 사용이 가능하며 명시적으로 열을 선택하여 결과 값 출력이 가능합니다. 또한 연산 조건문등의 사용이 가능합니다.

'CS공부 > 데이터베이스' 카테고리의 다른 글

[DB] 정규화 너무 어렵습니다.  (1) 2025.01.02
[DB] Index? 인덱스가 뭔가요  (1) 2024.12.28

안녕하세요!

오늘은 데이터베이스의 정규화 관련해서 자세히 알아보겠습니다.

 

SQL자격증, 정보처리기사, 컴퓨터 활용능력 3개의 자격을 취득하면서 DB 부분에서 항상 저를 괴롭히고 작성하는 현재까지도 잘 이해하지 못하고 있는 정규화 입니다. 시작하겠습니다!

정규화(Normalization)

정규화는 데이터베이스를 체계적이고 효율적으로 관리하기 위해서 사용되는 과정인데요 정규화를 실행함으로써 데이터베이스는 데이터 중복을 줄이고 데이터의 무결성과 일관성을 확보하게 됩니다.

정규화는 6개의 단계로 나뉘고 단계별로 데이터 구조를 개선하는데 초점이 있습니다.

도부이결다조

아주 익숙하죠 ㅎㅎ 저만 그런지는 모르겠지만 공부할땐 시간에  쫓겨 이해를 포기하고 암기를 하게됩니다..

저는 정규형을 볼 때마다 초면인 느낌이였지만 그래도 이거 하나는 외웠습니다. '도부이결다조' 6단계별 수행되는 키워드를 앞글자만 따서 만들었는데요 하나씩 봐보겠습니다.


도 : 메인이 원자값을 갖는다.

부 : 분 함수 종속 제거

이 : 행함수종속 제거

결 : 정자가 후보키 아닌 것 분해

다 : 치종속 제거

조 : 인종속 제거

 

자 각 단계별 정규형인데요 다시봐도 정말 말이 어렵습니다. 도메인이 원자값..? 이행함수종속 제거?? 정말 신선한 언어들이에요 이제 이 정규형들을 하나씩 봐보겠습니다.

제 1정규형 : 한 셀에는 한개의 데이터만

자 왼쪽의 학생 테이블을 먼저 보겠습니다. 학생의 이름과 수강하고 있는 과목이 보이는데요 구조상 보이는 장점으로는

우선은 학생별로 1개의 row만 사용하기때문에 저장공간을 많이 차지하지는 않겠네요 그리고 한 학생의 데이터만 조회할 경우에는 쉽게 데이터를 볼 수 있겠습니다.

 

하지만 '수학을 수강하는 학생을 찾아주세요' 나 '홍길동 학생의 수강과목에서 수학을 빼주세요' 라는 요청이 있을 때
어떻게 해야할까요? Select를 사용한 조건이나 과목 수정이 꽤나 까다로워 보입니다. 이때 사용하는것이 제1 정규형 입니다.

 

제 1정규형은 '한 컬럼에는 한 개의 값'을 넣자 입니다. 1정규화를 적용한 오른쪽 테이블을 확인해보면 보다 테이블의 구조가 단순해졌고, 데이터를 검색하거나 정렬하는 작업을 보다 쉽게 할 수 있겠네요

제 2정규형 : PK의 일부와만 관련있는 정보는 분리하자

제2 정규형은 우선 제1 정규형을 만족하는 테이블에서 시작합니다. 또한 우리는 부분 함수 종속 제거 라는 이름으로 알고 있습니다. 

 

왼쪽의 학생테이블에서 기본키는 어떻게 사용할 수 있을까요? 학생 ID와 이름은 중복됐으니 (학생ID + 과목)의 복합키로 

구성될텐데 이 때 강사이름은 핵심 주제인 학생과는 전혀 관련이 없으며 복합키 중 하나의 부분집합인 '과목'에 의해 결정되는 것이죠 이 경우를 부분함수종속을 제거하여 완전 함수 종속을 만족하는 제2 정규화 라고 합니다.

 

제2 정규형은 '주제와 상관없는 내용은 분리하자' 입니다. 2정규화를 적용한 오른쪽 테이블을 보면 데이터구조가 훨신 명확해진것을 확인할 수 있습니다.

하지만 단점으로는 어쨌든 관리해야할 테이블이 더 늘어났고 이제 학생 테이블 만으로는 강사를 알수 없으니 join문을 통해학생별 강사를 확인할 수 있게 되어 데이터 조회 성능이 저하될 수 있겠습니다.

제 3정규형 : 정말 필요없는 내용 없애기

제 3정규형은 2정규형을 만족한 테이블에서 이행 함수 종속을 제거한다고 알고 있는데요 

위 테이블을 예시로 성별 테이블은 우선 과목 테이블의 PK인 과목명에 의해 결정되지 않으며 기본키가 아닌 속성 (=강사)에 의존하고 있는것을 볼 수 있습니다. 

 

즉 일반 컬럼이 PK가 아닌 일반 컬럼에 종속되어있는 '이행 종속'을 제거하는 것입니다.

 

제3 정규형은 '정말 필요없는 내용은 분리하자' 입니다. 과목 테이블의 성별은 과목 테이블과는 관련도 없지만 강사 컬럼에 의존하고 있으니 이는 분리해서 더 명확한 구조로 관리하는것이 핵심 입니다.

이것도 2정규형과 단점이 비슷한데요 성별에 대한 정보는 과목 강사별 성별 정보는 join문을 통해 확인해야하니 데이터 조회 성능이 저하될 수 있습니다.

BCNF ~ 제5 정규화

사실 이 BCNF 이상의 정규형부터는 실행되는 경우가 별로 없습니다. 대부분 3정규형 까지 실행하면 충분히 구조를 세우고 문제를 해결할 수 있고 과한 정규화는 오히려 성능적 문제를 야기하기 때문에 성능 최적화가 우선되는 실무에서는 잘 사용하지 않습니다.

 

그래도 간단하게 설명해보겠습니다

 

BCNF 정규화 : 후보 키가 아닌 값이 결정자는 없애자

 => 후보키에 해당하지 않는 컬럼이 테이블의 컬럼 값을 결정하고 있을 경우 따로 분리한다.

제 4정규형 : 같은 키로 여러 값이 묶일경우 분리하자

 => 하나의 키에 여러 독립적인 값이 엮여있을 경우 각각의 테이블로 분리하자

제 5정규형 : 조인하지 않아도 되도록 데이터를 분리하자

 => 조인을 통해서 데이터를  확인할 수 있는 A,B,C 데이터 가 있을 때 AB, BC, AC 형태로 테이블을 분리시켜 데이터를 확인할 수 있다.

 

오늘은 데이터베이스의 정규화에 대해 알아봤습니다.

감사합니다!

 

 

 

 

'CS공부 > 데이터베이스' 카테고리의 다른 글

[DB] 조인? 헷갈립니다.  (1) 2025.01.02
[DB] Index? 인덱스가 뭔가요  (1) 2024.12.28

안녕하세요

이번엔 자바의 제네릭(Generic)에 대해 알아보도록 하겠습니다.

 

제네릭

제네릭의 정의를 보겠습니다. '제네릭은 타입 파라미터를 사용하는 프로그래밍 방식으로, 클래스나 메서드가 다양한 데이터 타입에서 동작할 수 있도록 합니다.'라고 합니다. 

 

저는 말이 조금 어려워서 풀어서 설명해 보겠습니다.

public void setName(String name)

우리가 아는 파라미터는 위 메소드의 name처럼 매개변수를 얘기하는데요 그럼 타입 파라미터가 의미하는 것은 무엇이냐

 

// 리스트 인터페이스
public interface List<E> extends Collection<E>;

// 리스트 구현
List<String> list = new ArrayList<>();
List<Integer> list = new ArrayList<>();
List<Boolean> list = new ArrayList<>();

리스트의 인터페이스와 리스트를 구현한것을 확인해 보면 알 수 있습니다.

 

List옆에 <E>가 바로 타입 파라미터를 받는 제네릭 기술을 사용한 것인데요 List는 제네릭을 이용해서 사용하려는 타입을 파라미터로 받기 때문에 우리가 list를 구현할 때 String, Integer, Boolean 등 다양한 자료형을 타입 파라미터로 전달하고 해당 자료형을 갖는 리스트를 사용할 수 있는 것이죠

 

제네릭은 메서드나 클래스를 작성하는 시점에 타입을 지정하지 않고 사용할 때 타입 파라미터를 통해 타입을 지정할 수 있도록 해주는 기능입니다.

특징

타입 안정성

제네릭이 주는 장점 중 하나로 타입 안정성을 보장한다는 것입니다. 타입 안정성은 변수, 메소드, 클래스에서 특정 데이터 타입에 대한 일관성을 유지하도록 보장하는 기능입니다.

List list = new ArrayList();
list.add("hello");
list.add(3);
		 
String value = (String) list.get(1);

자 위와 같은 코드가 있다면 어떻게 될까요? 문자열 형태의 value 변수에 숫자 3을 넣으려고 하는데요 컴파일 시점에서는 문제가 없습니다. 그런데 프로그램이 실행 중인 런타임 시점에서 Integer형태인 숫자 3은 String으로 형변환이 불가능하고

프로그램이 실행 중인데 오류가 발생하여 중단되는 아주 안 좋은 상황이 발생할 수 있습니다.

 

이제 제네릭을 사용하여 타입 안정성을 챙겨보겠습니다.

List<String> list = new ArrayList();
list.add("hello");
list.add(3); // 오류 발생
		 
String value = (String) list.get(1);

리스트는 문자열 타입 파라미터로 생성했습니다. 이때 컴파일 시점에서 list.add(3)은 오류가 발생하게 됩니다. String형태의 값만 넣을 수 있는데 Integer 형태의 값을 넣으니 오류를 보여주는 것이죠 이렇게 타입 안정성을 확보하여 개발시점에서 오류를 체크하고 방지할 수 있는 겁니다.

코드 재사용성

위에서 작성한 List를 생각하시면 쉽습니다. 리스트 인터페이스 하나로 String, Integer, Map 등등 다양한 타입의 자료를 사용할 수 있어 범용적인 코드를 사용할 수 있습니다.

 

동작 원리

제네릭이 내부적으로 어떻게 동작하는지 알아보겠습니다.

제네릭은 실행되며 타입 소거 현상이 일어납니다. 타입 소거 현상은 우리가 지정한 타입이 컴파일 되어 실행될 때 타입정보가 사라지는 것인데요 

// 작성 코드
List<String> list = new ArrayList();
list.add("hello");
		
String value = list.get(0);

// 타입소거 후 실행되는 코드
List list = new ArrayList();
list.add("hello");
		
String value = (String) list.get(0);

모든 타입 정보는 Object 형태로 변환되고 데이터를 넣는곳에서 자동으로 형변환을 시켜주는 방식입니다.

그렇기에 형변환을 하지 못하는 원시타입의 형태들은 제네릭의 타입으로 사용되지 못하는 겁니다.

 

오늘의 자바의 제네릭에 대해 알아봤습니다.

감사합니다!

안녕하세요 오늘은 자바의 데이터 유형인 원시 타입을 자세히 알아보겠습니다.

 원시타입 (Primitive Type) 

우리가 처음 자바를 배울 때 자료형에 대해 배웁니다. 

정수형의 byte, short, int, long

실수형의 float, double

문자형의 char, String

논리형의 boolean

 

하지만 아래 글에서 말했듯 String은 혼자 성질이 다른 객체이고 다른 자료형들은 원시 타입이라고 합니다.

https://nnmmyy.tistory.com/47

 

[자바] String, StringBuffer, StringBuilder

안녕하세요오늘은 자바의 문자열을 다루는 자료구조인 String 계열에 대해 알아보도록 하겠습니다. StringString은 문자열을 담는 자료형으로 처음 배웁니다. 프로그래밍을 처음 시작하는 사람은

nnmmyy.tistory.com

자바는 객체지향 언어입니다. 객체를 통해 유지보수성과 확장성을 높이도록 설계된 언어이지만 원시타입만은 객체로 설계되지 않았습니다.

 

그 이유는 성능에 있습니다. 연산 성능은 높을수록 좋기때문에 위 자료형처럼 수학 계산이나 조건문등에서 원시타입을 활용하게 된 것이죠 원시타입은 값 자체를 메모리에 저장하기 때문에 참조타입에 비해 더 빠르고 직접적으로 데이터를 가져올 수 있어 성능적으로 최적화가 가능했기 때문입니다.

 

즉, 원시타입의 목적은 값 연산 및 단순 데이터 저장에 있습니다.

Wrapper 클래스

원시타입은 값 계산 및 단순 데이터의 저장에 있지만 이를 넘어 값 활용이 필요한 경우가 있습니다.

int num1 = Integer.parseInt("11");
int num2 = Integer.max(1, 2);

문자열로 넘어온 값을 정수형태로 변경하거나 둘 중 큰 값을 찾기 위해 max 함수를 활용해 본 경험이 있으실 겁니다.

이렇게 단순 값 저장을 넘어 기능적으로 데이터를 활용하려 할 때는 원시 타입의 객체화가 필요한데 이를 실행하는 것이 Wrapper 클래스입니다. 원시 타입의 변수를 참조 타입의 변수로 변환시켜 객체화를 시켜주는 것이죠

Integer, Boolean, Character 같은 클래스가 존재합니다.

오토 박싱 / 언 박싱

ArrayList<Integer> list = new ArrayList<>();
list.add(10);
int num1 = list.get(0);

오토박싱과 언박싱은 Wrapper 클래스를 편하게 사용할 수 있도록 자바에서 만들어진 기능입니다.

자 위 형태의 코드를 보면 조금 이상한 게 보일 겁니다. Integer는 참조 자료형이고 int는 원시 타입으로서 서로 다른 자료형임에도 상호 간 데이터 교환이 자유로운 것을 볼 수 있습니다.

ArrayList<Integer> list = new ArrayList<>();
list.add(10);
 => list.add(Integer.valueOf(10)); // 오토박싱
int num1 = list.get(0);
 => int num1 = list.get(0).intValue(); // 언박싱

우리가 작성한 코드는 컴파일 과정에서 위처럼 오토박싱, 언박싱 과정을 자동으로 수행해서 편리하게 사용할 수 있는것이죠!

Null

원시타입은 null값을 허용하지 않습니다. Null의 뜻은 '참조하는 값이 없다.' 입니다. 원시타입은 메모리 에 직접 값을 저장하기 때문에 참조형의 Null값은 허용하지 않습니다. 

하지만 위에서 얘기한 Wrapper 클래스를 이용해서 원시 타입을 객체로 다루게 되면 Null값을 사용할 수 있습니다.

Collection

자바에는 List, Set, Map 같은 컬렉션들이 존재합니다. 컬렉션은 데이터를 효율적으로 다룰 수 있게 해주는 자료구조 인데요 이 컬렉션에는 원시타입의 자료형들은 사용할 수 없습니다.

그래서 Wrapper 클래스로 감싼 후에 사용하게 되죠 이는 컬렉션들이 타입 안정성을 위해 제네릭 기술이 사용됐기 때문인데요 제네릭은 별도의 포스팅으로 하고 간단하게 설명하면 제네릭으로 설정된 타입은 컴파일시에 Object 형태로 변환되는데 원시타입은 객체형태가 아니라 형변환이 불가능하여 컬렉션 사용을 하지 못합니다.

 

오늘은 자바의 원시 타입에 대해 알아봤습니다.

감사합니다!

 

 

안녕하세요

오늘은 세션과 쿠키, 토큰에 대해서 알아보겠습니다.

HTTP

오늘의 주제는 기본적으로 HTTP에서 출발하게 됩니다. HTTP는 서버에 정보를 저장하지 않는 무상태성(Stateless)를 원칙으로 만들어졌기 때문에 웹을 사용하며 사용자 인증, 상태유지를 하기위해서는 추가적인 기술이 필요한데요 이 때 사용하는것이 세션,쿠키,토큰 입니다.

세션

세션은 전통적으로 많이 사용된 인증 수단인데요 주요한 특징은 인증 데이터를 서버에서 관리한다는 것입니다.

클라이언트의 요청을 받으면 서버는 세션정보를 저장하고 세션ID를 발급해 쿠키에 담아 클라이언트에 전달하게되고 이 쿠키는 사용자 클라이언트에 저장되어 추후 요청시마다 쿠키에서 세션 ID를 함께 전달하게 되고 서버는 이를 통해서 인증상태를 관리하게 됩니다. 

 

세션 방식의 장점으로는 안전성에 있습니다. 민감 정보를 서버에서 관리하기때문에 위변조의 위험이 클라이언트 저장보다 적습니다. 그리고 HTTP의 주요 원칙인 무상태성을 보완하기 위해 만들어져 세션은 Stateful한 상태를 가지게 되고 또한 세션은 서버의 별도의 저장공간을 차지하기에 확장성에서 떨어지는 모습을 보이게됩니다.

토큰

토큰 방식의 가장 큰 특징은 무상태성 인증 방식을 지원한다는점 입니다. 토큰 방식은 토큰 자체에 사용자의 인증정보가 담겨있고 이를 서버와 통신하기에 서버에서는 사용자의 인증정보를 관리할 필요가 없는 장점이 있는것이죠 

클라이언트에 위치하기에 위변조 위험이 있지만 이는 비밀키를 사용한 암호화로 보호되기에 보안 문제를 극복 가능합니다. 

 

토큰의 특징인 무상태성은 확장성을 확보할 수 있게되고 이는 최근 자주 사용하는 RESTFUL API나 MSA 환경에서 유연한 방식으로 인증정보를 관리할 수 있게 합니다.

 

 

 

'CS공부 > 네트워크' 카테고리의 다른 글

[네트워크] HTTP 프로토콜  (0) 2024.12.29
[네트워크] REST와 MSA 2 - MSA  (0) 2024.11.27
[네트워크] REST와 MSA 1 - REST  (0) 2024.11.27

안녕하세요

오늘은 자바의 Object와 그 안에 equals, hashcode 메소드를 확인해 보겠습니다.

Object

Object는 자바의 모든 클래스들의 최상위 클래스입니다. 모든 클래스는 명시적으로나 암묵적으로 Object를 상속받고 있어서 우리는 모든 객체에서 .tostring(), equals(), .hashcode() 같은 메소드를 사용할 수 있는것이죠

 

Object를 상속받으며 모든 객체에 위에 적은 일관된 동작과 메서드를 제공하고 모든 객체를 Object 타입으로 참조할 수 있기에 자바의 특징인 다형성이 가능합니다.

 

Object를 상속받지 않는 타입은 바로 원시 타입 입니다. 원시 타입은 객체가 아니며 단순한 값만 저장하기에 상속을 받지 않지만 Wrapper클래스로 객체화 시켰을때는 Object 클래스를 상속받게됩니다.

equals()

Object가 제공하는 equals 메소드는 두 객체가 동일한지(논리적 동등성) 비교하는 메소드 입니다. 단어가 어렵지만 쉽게 얘기하면 두 객체의 메모리 주소가 일치하는지를 비교하는 메소드 이죠

 

Object 클래스를 확인해보면 아래와 같은 기본 코드를 확인해볼 수 있습니다.

public boolean equals(Object obj) {
    return (this == obj);
}

 

대부분의 클래스는 이 equals()를 오버라이드 하여 사용하는데요 예시로 String의 equals() 메소드를 확인하겠습니다.

public boolean equals(Object anObject) {
	// 메모리 주소가 같은지 확인
    if (this == anObject) {
        return true;
    }
    // 비교 대상이 String 인스턴스인지 확인
    if (anObject instanceof String) {
        String aString = (String)anObject;
        // 비교 대상의 인코딩 확인
        if (coder() == aString.coder()) {
        	// 비교 대상의 값 확인
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                              : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

String 클래스에서 equals의 목적은 내부의 값이 같은지 체크하는데에 목적이 있습니다. 그래서 위 처럼 과정을 거쳐 비교 대상의 값을 비교하는 방식으로 오버라이딩을 했습니다.

hashCode()

hashCode는 객체의 해시코드를 반환하는 메서드인데요 객체의 메모리 주소를 기반으로 해시함수를 통해 고유한 정수값을 반환해줍니다.

public native int hashCode();

 

오브젝트 클래스의 해쉬코드 함수는 메모리에 접근하는 네이티브 함수입니다.

 

마찬가지로 String의 hashCode()를 확인해 보겠습니다.

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        hash = h = isLatin1() ? StringLatin1.hashCode(value)
                              : StringUTF16.hashCode(value);
    }
    return h;
}

 

여기서 주의해야할 점은 equals메소드를 오버라이드 했다면 마찬가지로 hashcode메소드 또한 오버라이드 해줘야한다는 것입니다. 

 

hashCode 결과값을 바탕으로 hash 컬렉션들이 작동하게 되는데 만약 String 클래스가 아래와 같은 기본 hashCode() 메소드를 가졌다고 생각해 보겠습니다. 

public native int hashCode();

//

String a = "hello"
String b = new String("hello")

이렇게 되면 a와 b는 같은 값을 가졌지만 다른 hashCode를 반환하게 될것입니다.

 

이때 해시기반 자료구조를 사용하면 같은 값이지만 a,b를 각각 다른 버킷에 값을 저장하게 되는것이죠 HashMap에 두 데이터가 각각 들어가 있다고 했을때 Map.remove("hello")를 하게되면 중복값임 에도 불구하고 b의 해시코드 값을 찾지 못해 맵 안에 데이터가 남아있는 현상이 발생할 수 있습니다.

 

equals()와 hashcode의 일관성을 통해서 컬렉션이 올바르게 동작하도록 하는것이죠!

 

오늘은 Object와 equals, hashCode에 대해 공부해봤습니다.

감사합니다!

+ Recent posts