연산자 (Operator)

연산자와 피연산자

연산자(Operator): 연산을 수행하는 기호 (+, -, *, /, 등)

피연산자(Operand): 연산자의 작업 대상 (변수, 상수, 리터럴, 수식)

식과 대입연산자

식(Expression): 연산자와 피연산자를 조합하여 계산하고자 하는 것을 표현한 것

평가(Evaluation): 식을 계산하여 결과를 얻는 것. 하나의 식을 평가하면, 하나의 결과를 얻는다.

대입 연산자(=): 식의 평가결과를 변수와 같이 값을 저장 할 수 있는 공간에 결과를 저장할때 사용.

연산자의 종류

종류 연산자 설명
산술 연산자 +, -, *, /, %, <<, >> 사칙연산과 나머지(%) 연산. bit shift 연산.
비교 연산자 >, <, >=, <=, ==, != 크고 작음과 같고 다름을 비교.
논리 연산자 &&, ||, !, &, |, ^, ~ AND와 OR으로 조건을 연결.
'|'은 OR연산자, '&'은 AND연산자, '^'은 XOR연산자, '~'은 NOT연산자
대입 연산자 = 우변의 값을 좌변에 저장.
기 타 (type), ? :, instanceof 형변환 연산자, 삼항연산자, instanceof 연산자
  • 삼항 연산자는 오직 '? :' 뿐이다.

연산자의 우선순위와 결합규칙

종류 결합규칙 연산자 우선순위
단항 연산자 ++, --, +, -, ~, !, (type) 높음
산술 연산자 *, /, %
+, -
<<, >>, >>>
비교 연산자 <, >, <=, >=, instanceof
==, !=
논리 연산자 &
^
|
&&
||
삼항 연산자 ? :
대입 연산자 =, +=, -=, *=, /=, %=
<<=, >>=, &=, ^=, |=
낮음

Shift 연산자 (<< , >> , >>>)

  • 정수형데이터에서만 사용가능하고 2진수로 표현했을때 각 자리를 오른쪽 또는 왼쪽으로 이동
  • 오른쪽으로 n비트 이동하면 피연산자를 2의 n승으로 나눈 것과 같은 결과이다.
  • '<<' 연산자의 경우, 피연산자의 부호에 상관없이 자리를 왼쪽으로 이동시킵니다.
  • '>>' 연산자는 음수인 경우 부호를 유지시켜주기 위해서 빈자리를 1로 채웁니다.
  • '>>>' 연산자는 부호에 상관없이 항상 0으로 빈자리를 채워줍니다.

산술 변환 (usual arithmetic conversion)

피연산자의 타입이 다르다면, 연산 전 형변환 연산자로 타입을 일치시켜야 한다.

자동 형변환 규칙이 적용되는 타입인 경우, 보통 작은 타입에서 큰 타입으로 자동 형변환이 수행된다.

연산 전 피연산자 타입의 일치를 위해 자동 형변환되는것을 '산술 변환' 또는 '일반 산술 변환'이라 한다.

  • 두 피연산자의 타입을 같게 일치시킨다. (보다 큰 타입으로 일치)
  • 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다. (ex. char + short → int + int → int) 이유는 int형이 JVM에서 효율적으로 처리할 수 있는 단위이기도 하며 오버플로우의 발생 확률을 줄이기 위해서.

실수형이 아닌 피연산자의 연산결과는 정수형이 되어 소숫점 이하의 결과가 버려진다. 따라서 실수 결과를 얻기 위해서는 피연산자 중 한쪽을 실수형인 float 혹은 double로 형변환 해야 한다.

728x90
반응형

'Language > JAVA' 카테고리의 다른 글

연산자 (2)  (0) 2021.07.29
형변환  (0) 2021.06.24
기본형  (0) 2021.06.24
변수  (0) 2021.06.21
JAVA란?  (0) 2021.06.17

스테이트풀셋

필요성

파드별로 각자 다른 persistant volume을 할당하고 싶으면 어떻게 해야 할까. 디플로이먼트의 파드 템플릿은 모두 동일한 pvc를 가지기 때문에 곤란하다.

특정 애플리케이션이 안정적인 네트워크 아이덴티티를 요구(ACL 구성 등)하면 어떻게 해야 할까. 파드 한개당 서비스 한개를 맵핑해야 할까.

스테이트풀셋 이해

이런 유형의 파드를 실행하기 위해 레플리카셋 대신 사용하는것이 스테이트 풀셋 리소스다.

스테이트풀셋은 애플리케이션 인스턴스가 각각 안정적인 이름과 상태를 가지며 개별적으로 취급해야 하는 애플리케이션에 알맞게 만들어졌다.

스테이트풀셋과 레플리카셋

애플리케이션을 애완동물과 가축으로 빗대어

스테이트리스 애플리케이션은 가축이다. 인스턴스가 교체되어도 사용자는 이를 알아차리지 못하고 이용하는데 문제도 없다.

스테이트풀 애플리케이션은 애완동물이다. 애완동물이 죽으면 사용자는 이를 바로 알아차리고 이용하는데 문제가 생긴다. 대체하려는 애완동물을 구할때도 이름과 생김새가 완전히 같은 애완동물을 찾아야 한다. 이에 스테이트풀셋은 초기에 PetSets라고 불렸다.

스테이트풀셋으로 관리되는 파드가 종료되면 새로 교체되는 파드 인스턴스는 이름, 네트워크 아이덴티티, 상태가 동일한 상태로 되살아난다. 각 파드는 다른 피어와 구별되는 자체의 볼륨 세트를 가지며, 예측 가능한 아이덴티티를 가진다.

안정적인 네트워크 아이덴티티

스테이트풀셋 A의 파드는 0부터 시작되는 인덱스가 할당되어 A-0, A-1 과 같이 지어진다.(파드 이름이 컨테이너의 host로 쓰인다.)

거버닝 서비스

스테이트풀 파드는 각각 다르므로 한개를 선택할 때 특정 파드를 선택 할 필요가 있다.

이런 이유로 거버닝 헤드리스 서비스를 생성해서 각 파드에게 실제 네트워크 아이덴티티를 제공해야 한다.

​ ex) default 네임스페이스의 foo라는 거버닝 서비스가 있고 파드의 이름이 A-0이라면,

​ FQDN은 a-0.foo.default.svc.cluster.local로 접근할 수 있다.

이는 레플리카셋으로 관리되는 파드에서는 불가능하다.

또한, foo.default.svc.cluster.local 도메인의 SRV레코드를 조회해서 모든 스테이트풀셋의 파드 이름을 찾는 목적으로도 DNS를 사용 할 수 있다.

스테이트풀셋 스케일링

스테이트풀셋을 스케일업하면 새로운 인스턴스는 다음 서수 인덱스를 갖는다.

​ ex) A-0, A-1 -> A-2

스테이트풀셋을 스케일다운하면 항상 높은 서수의 인덱스를 먼저 제거한다.

​ ex) A-0, A-1 -> A-2

안정적인 스토리지 제공

퍼시스턴트 볼륨과 퍼시스턴트볼륨클레임은 일대일로 맵핑되어 각 파드는 별도의 퍼시스턴트 볼륨을 갖는 각각의 퍼시스턴트볼륨클레임을 참조해야 한다.

볼륨 클레임 템플릿

스테이트풀셋은 파드 템플릿을 구성할 때 각 파드와 함께하는 볼륨 클레임 템플릿을 가질 수 있다.

퍼시스턴트볼륨클레임의 생성과 삭제

스테이트풀셋을 스케일 업하면 두개 이상의 API오브젝트(파드와 파드에서 참조하는 하나 이상의 PVC)가 생성된다. 하지만 스케일 다운을 할때는 파드만 삭제하고 PVC는 남겨둔다.

PVC가 삭제된 후 PV가 재활용되거나 삭제될수 있기 때문이다.

동일 파드의 새 인스턴스에 PVC 다시 붙이기

스케일 다운 이후 스케일 업을 하면 PV에 바인딩된 동일한 PVC를 연결 할 수 있다.

스테이트풀셋이 보장하는 것

스테이트풀셋은 두개의 스테이트풀파드 인스턴스가 절대 동일한 아이덴티티로 실행되지 않고, 동일한 PVC에 바인딩 되지 않도록 보장한다.

만약 파드 교체가 일어나는 경우 새로운 파드를 생성하기 전에 파드가 실행중이 아니라는 것을 확인해야 한다.

728x90
반응형

디플로이먼트(Deployment)

디플로이먼트는 레플리카 셋 대신 애플리케이션을 배포하고 선언적으로 업데이트 하는 리소스다.

디플로이먼트를 생성하면 레플리카셋 리소스가 생성되고, 레플리카셋 리소스가 파드를 관리한다.

  • 디플로이먼트를 만드는 이유

애플리케이션을 업데이트 할 때 추가 레프리카 셋을 만들고 배포를 하는 방식을 통제하여야 하는데, 이를 디플로이먼트가 관리한다.

ex) 낮은 수준의 배포(kubectl을 통한 배포)를 진행하는 중 작업중인 노드가 내려간다면, 배포 중간 상태로 배포가 마무리된다.

디플로이먼트가 레플리카셋을 생성, 레플리카셋이 파드를 생성

디플로이먼트를 작성하며 레플리카셋이 생성한 파드의 이름을 조회하면 <디플로이먼트 이름> + <레플리카셋 해시값> + <파드 해시값> 으로 구성된다.

레플리카셋의 이름은 <디플로이먼트 이름> + <레플리카셋 해시값> 으로 생성되며 이는 레플리카셋이 해당 파드를 관리함을 의미한다.

디플로이먼트가 파드의 템플릿 버전별로 레플리카셋을 생성하기 때문에, 파드 템플릿의 해시값을 사용하면 디플로이먼트에서 지정된 버전의 파드 템플릿에 대하여 항상 동일한 레플리카셋을 사용 할 수 있다.

디플로이먼트 전략

  • Rolling Update

    기본 전략. 하나씩 기존 파드를 제거하고 신규 파드로 교체한다.

  • Recreate

    모든 기존 파드를 삭제한 뒤 새로운 파드를 만들어 낸다. 서비스 다운타임이 발생한다.

신규 파드 업데이트 이후 레플리카셋이 남아있는 이유

$kubectl get rs 와 같은 명령으로 레플리카셋을 조회해보면 기존에 사용되었던 레플리카셋이 지워지지 않고 남아있다. 디플로이먼트에 의해 관리되는데, 업데이트가 끝난 이후에 왜 계속 남아있을까?

디플로이먼트 롤백

새로 배포된 파드 템플릿에서 오류가 발생한 경우 롤아웃을 되돌려야 한다. 이 때, 디플로이먼트를 사용하여 마지막 혹은 정해진 버전으로 쉽게 롤백할 수 있다. 삭제되지 않은 레플리카셋은 이 때 사용된다.

모든 개정 내역의 수는 디폴로이먼트 리소스의 editionHistoryLimit 속성에 의해 제한된다.(쿠버네티스 버전이 올라가면서 revisionHistoryLimit로 변경)

maxSurge와 maxUnavailable

  • maxSurge

    디플로이먼트가 의도하는 레플리카 수보다 얼마나 많은 파드 인스턴스 수를 허용할 것인지. 백분율 혹은 절대값으로 지정. 기본값 25%

  • maxUnavailable

    업데이트 중 의도하는 레플리카 수(Desired State) 기준으로 사용할 수 없는 파드 인스턴스 수. 백분율 혹은 절대값으로 지정. 기본값 25%

minReadySeconds

일정시간동안 준비상태를 검사하여 rollout하는 디플로이먼트 spec의 리소스 속성이다.

오작동 버전의 배포를 방지할 수 있다.

사용 가능한 파드가 되려면 minReadySeconds 기간동안 readiness probe가 성공해야 한다.

롤아웃 데드라인

기본적으로 10분동안 롤아웃이 진행되지 않으면 실패한것으로 간주된다.

디플로이먼트의 ProgressDeadlineExceeded 으로 확인 할 수 있다.

디플로이먼트 스펙의 progressDeadlineSeconds 속성으로 정의 할 수 있다.

728x90
반응형

서비스

세션 어피니티

동일한 명령을 실행하더라도 서비스 프록시가 각 연결을 임의의 파드로 전달하기 때문에 연결 할 때 마다 임의의 파드가 선택된다.

반면 특정 클라이언트의 모든 요청을 매번 같은 파드로 전달하려면 서비스의 세션 어피니티 속성을 기본값 None 대신 ClientIP로 설정해야 한다.

apiVersion: v1
kind: Service
spec:
    sessionAffinity: ClientIP
...

DNS를 통한 서비스 검색

  • 클러스터에서 실행중인 다른 모든 팟이 사용하는 kube-dns 라는 시스템 리소스가 있다.
  • kube-dns는 모든 서비스를 알고있는 쿠버네티스의 자체 DNS 서버.
  • 파드가 내부 DNS 서버를 사용할 지 여부는 각 파드 스펙의 dnsPolicy 속성으로 구성 할 수 있다.
  • 서비스 이름을 알고 있는 파드는 FQDN(Fully Quallified Domain Name)으로 통신 할 수 있다.위 curl은 클러스터 내부의 pod을 kubectl exec 명령을 통해 실행한 상태에서 수행한다. (클러스터 내부 통신이기 때문)
    • svc.cluster.local 은 모든 클러스터의 로컬 서비스 이름에 사용되는 클러스터의 도메인 접미사. 생략 가능하다.
    • 파드가 같은 네임스페이스에 있는 경우 네임스페이스도 생략할 수 있다. 단순히 서비스의 이름만 써도 된다.
    • 파드 컨테이너 내부의 DNS resolver 구성 /etc/resolv.conf 를 보면 이해 할 수 있다.
  • Ex) curl http://svc-orra-dev.ns-ordev.svc.cluster.local:8082
  • 서비스에 IP 핑은 할 수 없다.

외부 클라이언트에 서비스 노출

  • 노드포트로 서비스 유형(Type) 설정
  • 서비스 유형을 노드포트 유형의 확장인 '로드밸런서'로 설정
  • 단일 IP 주소로 여러 서비스를 노출하는 인그레스 리소스 만들기

노드포트

노드포트 타입 서비스를 만들면, k8s는 모든 노드에 특정 포트를 할당하고 서비스를 구성하는 파드로 들어오는 요청을 전달한다.

로드밸런서

로드밸런서 타입 서비스를 만들면, 일번적으로 클라우드 인프라에서 로드밸런서를 자동으로 프로비저닝하는 기능을 제공한다. 쿠버네티스가 로드밸런서 서비스를 지원하지 않는 환경에서 실행중인 경우 노드포트 서비스처럼 작동한다.

서비스를 생성하고 클라우드 인프라가 로드밸런서를 생성하고 IP주소를 서비스 오브젝트에 쓰면, 로드밸런서 IP주소가 서비스의 external IP 주소로 표시돤다.

외부 연결 특성의 이해

불필요한 홉

외부에서 노드포트로 서비스에 접속하는 경우, 서비스가 임의로 선택한 파드가 동일 노드일 수도 있고, 아닐수도 있다. 파드에 도달하려면 추가 네트워크 홉이 필요한 경우가 생길 수 있다.

외부 연결을 수신한 노드에서 실행중인 파드로만 외부 트래픽을 전달하도록 서비스를 구성할 수 있다. 서비의 스펙에 externalTrafficPolicy 필드를 설정하면 된다.

spec:
    externalTrafficPolicy: Local

하지만 로컬에 파드가 없으면 연결이 중단되어버린다. (Kubernetes 1.15 이상: 패킷이 다른 노드에 있는 구성원 pod로 전달)

클라이언트 IP가 보존되지 않음

클러스터 내 클라이언트가 서비스로 연결 할 때, 서비스의 파드는 클라이언트의 IP주소를 얻을 수 있다.

하지만 노드포트로 연결을 수신하면 패킷에서 소스 네트워크 주소 변환(source network address translation)이 수행되어 소스 IP가 변경된다.

예를들어 엑세스 로그에 브라우저 IP를 남길 수 없는 문제가 생길 수 있다.

하지만 externalTrafficPolicy를 설정 한 경우, 노드 사이에 추가 홉이 없기 때문에 SNAT이 수행되지 않는다.

인그레스

필요성

로드밸런서 서비스는 공용 IP주소를 가진 로드밸런서가 필요하지만, 인그레스는 한 IP주소로 수십개의 서비스에 접근이 가능하도록 지원해준다.

클라이언트가 http 요청을 인그레스에 보낼 때, 요청한 호스트와 경로에 따라 요청을 전달할 서비스를 결정한다.

인그레스는 L7에서 동작하며, 쿠키 기반 세션 어피니티 등과 같은 기능을 제공 할 수 있다.

레디니스 프로브(Readiness Probe)

주기적으로 호출되며 특정 파드가 클라이언트의 요청을 수신 할 수 있는 상태인지 결정한다.

Exec Probe

프로세스를 실행시켜 종료 상태 코드로 결정한다.

Http Get Probe

http get 요청을 보내 http 응답 상태 코드를 보고 준비 여부를 결정한다.

TCP Socket Probe

지정된 포트로 TCP 연결을 수행하여 소켓이 연결되면 준비된것으로 간주한다.

레디니스 프로브 동작

컨테이너가 시작 될 때 첫번째 점검을 수행하기 전 기다리는 시간을 구성할 수 있다.(initialDelaySeconds)

그 다음 주기적으로 레디니스 프로브를 수행한다. 파드가 준비 상태가 되지 않으면 서비스의 엔드포인트에서 제거된다. 준비되면 다시 서비스에 추가된다.

Liveness Probe와 다르게 준비 상태가 아니더라도 컨테이너가 재시작 되지 않는다.

레디니스 프로브 중요성

만약 프론트엔드 파드중 하나에 연결 문제가 발생해 더 이상 DB에 연결 할 수 없는 경우, 레디니스 프로브를 통해 쿠버네티스에 알려야 한다.

레디니스 프로브를 항상 정의해야 하는 이유

파드에 레디니스 프로브를 추가하지 않으면, 파드가 시작하는 즉시 서비스의 엔드포인트가 된다.

애플리케이션을 시작하는데 오래 걸리는 경우, 준비가 되지 않은 파드로 요청이 전달되어 "Connection refused"와 같은 에러를 보게 된다.

레디니스 프로브에 파드의 종료 코드를 포함하지 말아야 한다

쿠버네티스는 파드를 삭제하자마자 모든 서비스에서 파드를 제거하기 때문에, 레디니스 프로브에 파드의 종료 코드를 포함할 필요가 없다.

헤드리스 서비스

쿠버네티스가 서비스에 대한 DNS 조회를 수행하면 DNS 서버는 서비스의 클러스터 IP를 반환한다.

하지만 서비스 스펙에서 clusterIP 필드를 None으로 설정하면 서비스 IP 대신 파드 IP들을 반환한다.

이를 이용해 클라이언트는 하나 이상의 파드에 연결 할 수 있다.

이는 READY 상태가 된 파드만 보여주며 준비되지 않은 파드도 포함하려는 경우 서비스에 다음과같이 어노테이션을 추가해야 한다.

kind: Service
metadata:
    annotations:
        publishNotReadyAddresses: "true"

서비스 트러블슈팅

  • 외부가 아닌 클러스터 내에서 서비스 클러스터 IP에 연결되는지 확인한다.
  • 서비스에 액세스 할 수 있는지 확인할 때, 클러스터 IP에 핑을 때리는건 의미없다.(서비스의 클러스터 IP는 가상 IP임으로 핑에 응답하지 않음.)
  • Readiness Probe를 정의했다면 확인한다. publishNotReadyAddresses 어노테이션이 없다면 준비되지 않은 파드는 서비스에 포함되지 않는다.
  • 파드가 서비스에 포함되어있는지 확인하려면 'kubectl get endpoints'를 조회해 확인한다.
  • FQDN이나 그 일부로 서비스에 접근하는 경우, FQDN 대신 클러스터 IP로 접근해본다.
  • 대상 포트(target port)가 아닌 서비스의 포트로 연결되는지 확인한다.
  • 파드 IP에 직접 연결해 파드가 올바른 포트에 연결되어 있는지 확인한다.
  • 파드 IP로 접근할 수 없는 경우, 애플리케이션이 localhost에만 바인딩하는지 확인한다.
728x90
반응형

POD을 안정적으로 유지하기

컨테이너에 주 프로세스에 크래시가 발생하면 kubelet이 컨테이너를 재시작한다.

하지만 크래시 없이 애플리케이션이 중단되는 경우(ex. 자바 애플리케이션의 메모리누수로 OutofMemorysErrors가 발생해도 JVM 프로세스는 중단되지 않는다.)에, 쿠버네티스에 신호를 보내 애플리케이션을 재시작하도록 하는 방법이 있어야 한다.

Liveness Probe

각 컨테이너가 정상인지 확인한다. 프로브가 실패하는 경우, 컨테이너를 재시작한다.

spec에 지정 할 수 있다.

  • HTTP Get

    지정한 IP주소, 포트, 경로에 HTTP Get 요청을 수행한다.

    응답 코드가 4xx, 5xx와 같은 오류가 아니라 2xx, 3xx인 경우 성공.

    http 오류 코드 혹은 응답이 없는경우 실패.

  • Socket

    지정된 포트에 TCP 연결을 시도한다. 연결의 성공여부가 프로브의 성공여부.

  • Exec

    컨테이너 내의 임의의 명령을 실행하고 종료 코드를 확인한다.

    상태코드가 0이면 성공, 다른 모든 코드는 실패.

*크래시된 컨테이너의 로그 얻기

컨테이너가 재시작되면 kubectl logs 명령은 현재 컨테이너의 로그를 표시한다.

이전 컨테이너의 로그를 얻고 싶다면 --previous 옵션을 사용한다.

$ kubectl logs [POD] --previous

Liveness Probe 추가설정

delay

컨테이너가 시작된 후 일정시간 뒤에 liveness probe 실행 (ex. delay=0s)

timeout

컨테이너가 응답해야 하는 제한시간. 제한시간 내 응답 못할시 실패. (ex. timeout=1s)

period

liveness probe 실행주기. (ex. period=10s)

failure

몇 번 연속 실패하면 컨테이너가 다시 시작되는지에 대한 값. (ex. failure=3)

728x90
반응형

형변환

형변환이란?

변수, 또는 상수의 타입을 다른 타입으로 변환하는 것.

캐스팅(casting)이라고도 한다.

형변환 방법

(타입) 피연산자;

double d = 85.4;
int score = (int)d; // double 타입의 변수를 int로 형변환
  • 기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환 가능.

정수형간의 형변환

큰 타입에서 작은 타입(ex. int -> byte)으로 변환하는 경우, 크기 차이만큼 삭제되며, 값의 손실이 발생 할 수 있다.

작은 타입에서 큰 타입(ex. byte -> int)으로 변환하는 경우, 빈 공간은 0 또는 1로 채워진다. (값이 음수인 경우, 2의 보수법에 의해 1로 채워진다.)

실수형간의 형변환

작은타입(float)에서 큰 타입(double)로 변환하는 경우

  • 지수(E)는 float의 기저인 127을 뺀 후 double의 기저인 1023을 더해서 변환한다.
  • 가수(M)은 float의 가수 23자리를 채우고 남은 자리를 0으로 채운다.

double 타입에서 float으로 변환하는 경우

  • 지수(E)는 double의 기저인 1023을 뺀 후 float의 기저인 127을 더한다.
  • 가수(M)은 52자리중 23자리만 저장하고 나머지는 버린다. 이 때, 가수의 24번째 자리 값이 1이라면 반올림이 발생하여 23번째 자리의 값이 1 증가한다.
  • float의 범위를 넘는 값을 float으로 형변환하는 경우, '±무한대' 혹은 '±0'을 결과로 얻는다.

정수형과 실수형간의 형변환

실수형을 정수형으로 형변환

정수를 2진수로 변환 한 다음, 정규화를 거쳐 실수의 저장형식으로 저장된다.

이 때, 실수형의 정밀도 제한으로 인한 오차가 발생 할 수 있다.

실수형을 정수형으로 변환.

실수형을 정수형으로 변환하면, 소수점 이하 값은 버려진다. (반올림이 발생하지 않는다.)

자동 형변환

편의상의 이유로 생략된 형변환을 컴파일러가 자동적으로 추가하는 것.

자동형변환 규칙

기존의 값을 최대한 보존 할 수 있는 타입으로 자동 형변환한다.

표현범위가 좁은 타입에서 넓은 타입으로 변환하는 경우에는 값 손실이 없으므로 두 타입 중에서 표현범위가 더 넓은 쪽으로 형변환된다.

실수형은 정수형과 값을 표현하는 방식이 다르기 때문에 같은 크기일지라도 실수형이 정수형보다 훨씬 더 큰 표현 범위를 가진다.

  1. boolean을 제외한 7개의 기본형은 서로 형변환이 가능하다.
  2. 기본형과 참조형은 서로 형변환 할 수 없다.
  3. 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.
728x90
반응형

'Language > JAVA' 카테고리의 다른 글

연산자 (2)  (0) 2021.07.29
연산자 (1)  (0) 2021.07.11
기본형  (0) 2021.06.24
변수  (0) 2021.06.21
JAVA란?  (0) 2021.06.17

기본형(primitive type)

논리형(boolean)

boolean

  • 논리형은 boolean 한가지 뿐
  • true와 false 중 하나를 저장 할 수 있으며 default는 false이다.
  • 값은 0과 1, 즉 1비트만 있으면 되지만 JAVA의 기본 메모리 단위가 1 byte이므로 1 byte의 공간을 차지한다.
  • 예약어인 true와 false만 사용 가능하므로 True, False등은 사용 불가능.

문자형(char)

  • 문자형은 char 한가지 뿐
  • 문자의 유니코드(정수)가 저장된다. 유니코드를 직접 저장 할 수도 있다.
char ch1 = 'A';
char ch2 = 65;
// ch1 == ch2 -> true
  • 특수 문자 리터럴이 있다.
특수문자 문자 리터럴
tab \t
backspace \b
form feed \f
new line \n
carriage return \r
역슬래쉬 \\
작은 따옴표 \'
큰 따옴표 \"
유니코드 (16진수 문자) \u유니코드 (ex. char a = '\u0041')

정수형(byte, short, int, long)

  • byte, short, int, long 4가지 타입이 있으며 각 1byte, 2byte, 4byte, 8byte의 크기를 가진다.
  • 가장 왼쪽의 첫번째비트를 부호비트로 사용한다. (양수는 0, 음수는 1)
  • JVM의 피연산자 스택(operand stack)이 4 byte 단위로 저장하기 때문에 4byte보다 작은 값을 계산할 때는 4 byte으로 변환하여 계산한다. 따라서 int형의 연산이 byte 혹은 short보다 효율적이다.

실수형(float, double)

  • 실수를 저장하기 위한 타입.
  • 오버플로우가 발생하면 무한대가 되며, 언더플로우가 발생하면 0이 된다.
  • float은 정밀도가 7자리이며(7자리의 10진수를 오차없이 저장 가능하다), double은 15자리이다.
  • 실수를 부동소수점 형태로 저장하며, 부호(Sign), 지수(Exponent), 가수(Mantissa) 로 이루어져 있다.
  • 지수 부분에 의해 자릿수가 결정되며, 가수 부분에 의해 오차없이 저장할 수 있는 숫자의 범위가 결정된다.
728x90
반응형

'Language > JAVA' 카테고리의 다른 글

연산자 (2)  (0) 2021.07.29
연산자 (1)  (0) 2021.07.11
형변환  (0) 2021.06.24
변수  (0) 2021.06.21
JAVA란?  (0) 2021.06.17

변수란

단 하나의 값을 저장할 수 있는 메모리 상의 공간

변수 선언과 초기화

변수타입 변수이름;

변수타입

저장될 값의 타입. 저장하고자 하는 값의 종류에 맞게 선택.

변수이름

메모리 상의 공간에 값을 저장했으므로, 그 메모리 공간에 이름을 붙여주는 것.

같은 이름의 변수가 여러개 존재한다면, 메모리 공간을 찾아 갈 수 없으므로 같은 이름의 변수가 여러개 있으면 안된다.

변수 선언

변수를 선언하면, 메모리의 빈 공간에 변수타입에 맞는 저장공간이 확보되며, 이 저장 공간은 변수 이름으로 접근 할 수 있다.

변수 초기화

  • 변수를 선언했을 때, 메모리 공간에 쓰레기 값이 존재 할 수 있으므로 사용 전 초기화를 해야 한다.
  • 지역 변수는 반드시 초기화 이후에 사용 할 수 있다. 변수 종류에 따라 초기화 없이 사용할 수 있는 변수도 있다.
  • 클래스 변수와 인스턴스 변수는 초기화를 생략 할 수 있다.

변수 명명규칙

필수 규칙

  1. 대소문자가 구분되며 길이에 제한이 없다.
  2. 자바 예약어는 사용 할 수 없다. (true, default, super 등)
  3. 숫자로 시작할 수 없다.
  4. 특수문자는 '_'와 '$'만 허용한다.

선택 규칙

  1. 클래스의 첫글자는 대문자로 한다.
  2. 여러 단어로 이루어진 변수명은 첫글자를 대문자로 한다. (camelCase, PaskalCase)
  3. 상수의 이름은 모두 대문자로 한다. 여러 단어인 경우 '_'로 구분한다.

추가로, 자바의 모든 명명에는 유니코드 문자를 사용 할 수 있지만, 적어도 클래스 이름은 ASCII코드를 사용하여 작성하는것이 좋다. 유니코드를 인식하지 못하는 OS가 있기 때문이다.

변수 타입

값의 종류는 '문자'와 '숫자'로 나눌 수 있으며

이 중 '숫자'는 '정수'와 '실수'로 나눌 수 있다.

값의 종류에 따라 저장될 공간의 크기와 저장형식을 정의한것이 변수 타입이다.

  • 문자형: char
  • 정수형: byte, short, int, long
  • 실수형: float, double

기본형과 참조형

JAVA는 C언어와 다르게 참조형 변수 간 연산이 불가능하므로 실제 연산은 모두 기본형 변수를 사용한다.

기본형 변수

  • 문자형, 정수형, 실수형, 논리형(boolean) 총 8가지
  • 실제 값을 저장한다.
문자형

문자형 변수타입 char는 내부적으로 유니코드인 정수를 저장한다.(2 bytes)

정수형 혹은 실수형과 연산도 가능하다.

논리형

크기를 1byte 사용한다.

논리형 변수타입 boolean은 다른 기본형과 연산이 불가능하다.

정수형

정수형은 byte(1 byte), short(2 bytes), int(4 bytes), long(8 bytes) 네가지를 제공한다.

int 타입이 CPU가 가장 효율적으로 사용되는 타입이므로 연산이 빠르지만, 메모리 절약을 위해 byte나 short의 선언을 고려해 볼 수 있다.

실수형

실수형은 float(4 bytes), double(8 bytes)이 사용된다.

정수형의 int 타입이 기본 자료형인 것 처럼, 실수형은 double 타입이 기본 자료형이다.

참조형 변수

클래스이름 변수이름;

  • 기본형 변수를 제외한 나머지 타입
  • 어떤 값이 저장된 주소를 값으로 갖는다.
  • 변수의 타입으로 클래스의 이름을 사용.
  • null 또는 객체의 주소(4 byte 정수)를 값으로 가진다.

상수와 리터럴

상수란

final 변수타입 변수이름 = 초기화;

  • 변수와 같이 값을 저장 할 수 있는 공간이지만, 한번 값을 저장하면 변경 할 수 없다.
  • 반드시 선언시 초기화 하여야 하며, 이후 값을 변경 할 수 없다. (JDK 1.6부터는 한줄로 초기화를 하지 않아도 사용 전에만 초기화를 하면 되도록 바뀌었다.)

리터럴

상수란 1, 20, 'A'와 같은 값을 의미하는데, JAVA에서 상수란 '값을 저장 하면 변경 할 수 없는 메모리 공간'이기 때문에, 리터럴이라는 용어를 사용한다.

정수형

접두사

2진수: 0b (JDK 1.7부터 추가)

8진수: 0

16진수: 0x

접미사

int타입: 접미사 없음

long타입: 접미사 'l' or 'L'

JDK 1.7부터 정수형 리터럴 중간에 구분자 '_'을 넣을 수 있게 되었다.

실수형

접미사

float타입: f

double타입: d (기본형으로 생략 가능)

float pi = 3.14; // 리터럴 3.14는 d가 생략된 double타입 리터럴이므로 에러.

문자와 문자열 리터럴

문자 리터럴
  • 'A'와 같이 문자 하나를 감싼 것.
  • 단 하나의 문자만 저장 가능.
  • '' 안에 반드시 하나의 문자가 있어야 함.

문자열 리터럴

  • String 클래스 사용, 객체지만 특별하게 변수 타입처럼 선언 가능.
  • ""안에 아무런 문자도 넣지 않는 것 허용
  • 덧셈 연산자(+)는 피연산자 중 한쪽이 String이면 나머지 한쪽을 먼저 String으로 변환 후 두 String을 결합한다.
  • (EX. 7 + 7 + "7" = "147", 7+"7"+7+7 = "7777")
728x90
반응형

'Language > JAVA' 카테고리의 다른 글

연산자 (2)  (0) 2021.07.29
연산자 (1)  (0) 2021.07.11
형변환  (0) 2021.06.24
기본형  (0) 2021.06.24
JAVA란?  (0) 2021.06.17

+ Recent posts