728x90

불 연산 회고

이 2장 정리를 진작에 했어야 했는데 시간이 나지를 않아서 지금 포스팅하게 되었다.

모든 코드는 깃허브에 있다.

일단 저번 회고 때 마지막으로 정리했던것은 카르노맵 이었다.

카르노맵으로 뭔가의 공식들을 도출할 수 있으니까 논리식을 간소화한 후에 회로도를 셋팅하는 정도는 이제 무리가 없었다.

이게 정말 다행이었고 여기서부터는 이제 입력 값이 3개이기 때문에 3변수 카르노맵을 통해

풀게 되었다.

일단 2진수의 덧셈을 생각해보면 2진수는 0과 1로 이루어져있다.

일반적인 10진수에서 덧셈을 할때를 보면 10일때는 올림처리를 한다.

2진수도 마찬가지다 도합 2가 되면 올림처리를 해주는 것이다.

그것을 Carry라고 부른다.

KakaoTalk_20211023_155551656

자 반가산기 이다. 반가산기는 덧셈을 수행하는 가산기이며 입력값이 두가지 이다.

그러니까 처음 계산할 때 대부분 반가산기를 사용할 것이다.

2진수로 1 + 1 = 0 이 성립한다.

이때 X = 1, Y = 1인것이고 Carry(올림)이 1이다 왜냐면 저 0은 더해서 2가 되어서

올림 처리를 해주고 남은 0이라서 합계가 0이 되는 것이다.

그래서 진리표대로 잘 나오는 것을 확인하였고 이것을 토대로 카르노맵을

Carry의 입장, Sum의 입장에서 하나씩 구현을 했다.

이 반가산기는 언제쓰나 했더니 자세히 보니까 한자리 덧셈만 할 때,

이 때만 수행해준다.

전가산기

KakaoTalk_20211023_155551179

이 전가산기가 나온이유가 바로 위에서 반가산기 덧셈 후에

그러니까 맨 처음 덧셈을 수행할 때만 이렇게 해주고

나머지는 올림처리한 입력값 까지 같이 계산을 해야되니까

이 전가산기를 통해 나머지 연산을 해주어야 한다.

16비트 가산기

그래서 이 16비트 가산기가 설명을 하자면

예를들어 1111 + 1010 이 두개를 더한다고 해보자

1 1 1 1

1 0 1 0

맨 오른쪽인

1과 0을 보면 이제 이 부분이 반가산기로 연산을 수행하는 것이다.

1 + 0 은 0이고 Carry 또한 발생하지 않았기 때문에 그대로 진행하고 그 다음부터는 올린 수를 고려해야 하기 때문에

3개 입력 -> 이전 Carry 0 + 1 + 1이 되는 것이다.

HalfAdder

FullAdder

...

를 수행하게 된다.

이렇게 반가산기, 전가산기 두개로 가산기에 대해서 알아보았다.

ALU라는 2장의 끝판왕이 존재하는데 저번 회고에서

유튜브 페이지에 들어가서 Computer Science 탭에 ALU설명을 듣고나니까 구현할 수 있을것만 같다.

토요일에 구현해보고 다시 회고를 작성해보겠다.

728x90

'CS' 카테고리의 다른 글

Cache  (0) 2022.08.09
ALU 구현  (0) 2022.08.09
불 논리 정리 2  (0) 2022.08.09
불 논리 회고  (0) 2022.08.07
728x90

2진수

2진수는 0과 1로만 이루어져있는 수이다.

1bit의 단위를 가진다.

bit란?

2진수의 기본 단위이다.

패리티 비트

패리티 비트는 전달하는 데이터의 오류를 검증해주는 비트이다.

문자열 내 1비트의 모든 숫자가 짝수 또는 홀수인지를 보증하기 위해 전송하고자 하는 데이터의 각 문자에 1 비트를 더하여 전송하는 방법으로

2가지 종류의 패리티 비트(홀수, 짝수)가 있다. 패리티 비트는 오류 검출 부호 에서 가장 간단한 형태로 쓰인다.

실질적으로 오류를 확인할 수 있는 비트이지, 그 오류에 대한 해결을 할 수는 없다.

보수

보수는 사전적 의미로 보충을 해주는 수 라고 정의되어 있다.

숫자 2의 10의 보수는 8이 되는 것이다.

논리 회로에서의 보수는 뺄셈 연산을 할 때, 좀 더 효과적으로 수행하며

논리적 조작의 용이성을 위해 사용한다.

  • 1의 보수
    • 2^n -1 자리수 최대값에서 해당하는 이진수 값을 빼주면 그것이 바로 1의 보수
  • 2의 보수
    • 2^n - 1자리수 최대값에서 해당하는 이진수 값을 빼준 후에 1을 더해주는 보수

KakaoTalk_Photo_2021-10-30-15-58-08

1의 보수 감산

  1. 1의 보수 감산은 주어진 수들을 일단 2진수로 변환한다.
  2. 음수로 되어있는 수는 1의 보수를 취해준다.
  3. 서로의 자릿수가 다르다면 자리수를 맞춰준다.
  4. 앞에 양수면 0, 음수면 1의 부호비트를 붙여준다.
  5. 덧셈을 진행한다.
  6. 진행한 후에 자리올림(Carry)가 발생하면 최하위 비트에 1을 더해준다.

그 후 맨앞의 부호비트는 떼어놓고 나머지 수들의 자릿수만큼의 경우의 수(절대값)은

2^n-1에서 떼어놓은 나머지 수를 빼주고 10진수로 변환한다.

그리고 나서 부호비트를 표현해주면 그것이 보수감산하여 나온 값이 된다.

2의 보수 감산

2의보수는 1의보수 + 1 이기 때문에 1의보수 방법에서

보수로 변환을 해준 뒤에 + 1을 시켜준다.

마찬가지로 부호비트를 추가해주고 덧셈을 수행하면 된다.

그리고 나서 보수감산이 진행되고 나서 다시 +1을 해준다.

불대수 법칙

이전 포스팅에서도 정리를 했었는데, 다 알고있던건 수기로 작성했고

드모르간 정리는 저번 포스팅 때에 존재하였기 때문에,

제2 분배법칙을 따로 증명해보았다.

그게 바로 X + YZ = (X+Y)(Y+Z) 이런 법칙이다.

(X+Y)(X+Z)를 분배해서 일일이 나열하게 되면

XX + XY + XZ + YZ 가 되는데,

여기서 XX + XY를 X에 대해 묶어주면

X(1 + Y)가 된다.

기본법칙에서 1 + 변수는 1이되므로 생략이 된다.

그래서 저 식을 풀면 그냥 X가 된다.

정리를해보면 X + XZ + YZ 가 남게 되는데 여기서 또,

X에대해서 X + XZ를 묶어주게 되면

X(1 + Z)가 되어서 또다시 X가 된다.

그래서 최종적으로 보게 되면 X + YZ 가되어 두식이 같다는걸 증명했다.

이제 좀 탄력을 받아서 ALU 구현하는데에 도전해볼 것 같다는 확신이 든다.

유튜브 페이지에 들어가서 Computer Science

아주 좋은 강의가 순서대로 있었다.

논리게이트부터 CPU까지만 지금 들었지만 굉장히 이해하기 쉽고 재밌게 설명해서

보면서 감탄만 한것 같다.

728x90

'CS' 카테고리의 다른 글

ALU 구현  (0) 2022.08.09
불 연산 회고  (0) 2022.08.09
불 논리 회고  (0) 2022.08.07
HTTP  (0) 2022.08.07
728x90

업무 회고

3개월 좀 넘게 이제 지금의 회사를 다니는 중인데,

사실 정말 짧은기간이라고 봐도 무방하다.

근데 이 3개월동안 회사에서 했던건 정말 많았다.

왜냐면 내가 지금 혼자 백엔드를 맡아서 개발하고 있으니까 말이다.

전에 있던 백엔드분은 보지도 못했고 따로 인수인계 받은게 없었으니

기존의 기능에서 추가적으로 개발하는데 꽤나 애를 먹었었다.

인수인계 과정

그러니까 지금 백엔드 프로젝트 1개가 인계한 순서가

전 백엔드 근무자 → 프리랜서 → 나

이 순서로 인계가 되었기 때문에 뭐 제대로 받은게 없었다.

당연히 받은 코드도 이해하는데 꽤나 걸렸으며,

특히 테스트 코드 가 없었다....

어떤식으로 돌아가는지에 대한 이해를 전혀 할 수가 없어서 짜증이 났지만,

그래도 이게 또 기회랍시고 나는 넥스트스텝의 TDD 과정을 들은 것을 토대로 테스트를 작성했다.

테스트 코드

테스트 코드는 정말 작은것부터 시작을 했다.

누구한테 물어볼 그런것도 없었거니와, 추가적으로 알아야 하는것은 구글신 에게 의존하는 수 밖에 없었고, 그러면서 동시에 어떤 라이브러리에 대한 공식문서 보는것이 좀 당연해졌다.

지금 구조는 회사의 백엔드 기술력이 오로지 나 혼자가 일궈낸 것이 되는것이다.

처음 왔을 때부터 그랬으니까 뭔가 도입하거나 하려는 것도 내가 배워서 적용만 하면

되는것인데,

방향을 잡아줄 수 있는 사람이 없다는 것 이게 정말 아쉬운 부분이었다.

하지만 단위테스트를 적용해놓고나서 보니까 중복된 코드도 많이 보였고,

쓸모없는 로직, 불필요한 주석

추가적으로 어떤 변수에 대해 사용하지 않은데 향상된 for문, 람다 forEach가 섞여있는 모습들이 많았다.

무조건 분기해서 만든 긴 ifElse 조건문들...

와서 모두 디자인패턴에 대한 공부, TDD Clean Code with Java 12기 에 학습하면서

다 안좋게 보여서 전부 고쳤다.

테스트가 항상 통과되고 안전하다는 보증을 서줬기 때문에 믿고 막 고칠 수 있었던것 같다.

협업

협업에서도 아쉽지만 우리 회사에는 Git에 대해 좀 생소할 수도 있고, Jira, Slack 등등... 사용하지를 않아서 협업 질문에 대해서 다 협업은 하고싶다고들 얘기를 하셨다.

그렇기 때문에 Git Flow에 대해서 회의실에서 내가 발표를 하고 이 Flow대로 Git을 제대로 사용해보자 도입해보자 건의를 했다.

대답들은 전부 긍정적이셔서 이렇게 협업의 장을 내가 열었다(?) 고 봐도 될 것이다.

Jira에 대해서는 들어는 보셨지만, 사용해보지는 않았다고 하셔서 이전 직장에서의 사용했던 경험과, 그리고 지금 진행중인 스터디 에서 사용했던 거로 설명을 전부 했었다.

그리고 제일 중요했던 것...

스웨거 도입

여태 API문서 에 대한건 전부 엑셀파일로 백엔드 개발자 분이 직접 만들거나 또는 Postman에 올리거나 하는식으로 진행을 했다고 한다....

당시에 나는 이 방식이 정말 귀찮았다.

이거를 내가 API 개발함과 동시에 문서화를 하는게 낫다고 판단했다.

왜냐면 서버가 돌아가면서 그안에서 테스트를 해볼 수 있기 때문이었다.

그리고 구축을 해두었으니 별도로 따로 타이핑을 해서 문서화 해야하는 불편함을 좀 덜 수 있었기 때문이다.

그래서 Spring Rest DocsSwagger 2 중에 고민을 했지만,

디자인이 좀 알록달록하고 Spring Rest Docs보다 Swagger가 설정이 좀 더 편했으니

이게 좀 더 합리적이라고 생각했다..

프론트엔드 한분이 스웨거는 많이 보셨다고 한게 한번의 작용을 했다고도 볼 수 있다. ㅋㅋㅋㅋㅋㅋㅋ

여기까지 해서 GitSwagger, Jira까지 협업에 대한 밑바닥부터 조금 만들었다.

마이그레이션 경험

일단 Mybatis 기술을 사용한 것이 정말 많았다...

이 기술 쓰는 것 그 자체에 대한 고찰이 생겼었는데

그 이유는 바로 명색이 백엔드 그것도 자바 개발자인데,

Mybatis 안의 그 핵심 쿼리들, 그리고 그 안에 비즈니스 로직을 다 넣게 되는 것이다.

그래서 원하는 데이터만 딱딱 뽑아오게끔 거의 설계가 됐었다.

전직장도 동일하다(물론 iBatis였지만)

자바를 많이 보고 객체지향적인 고민을 하는것이 아니라,

데이터적인 생각, 항상 데이터만 이렇게 가져오면 된다에 심혈을 기울여서

쿼리에서 데이터만 받아서 처리해주면 된다. 라는 생각만 갖게 됐던 것 같다.

그래서 이를 탈피하고자 이전에 Django 팀 프로젝트를 했을때 사용했던 ORM을 생각해서

공부하려고 JPA스터디를 참여하였다.

좋은 사람들을 만났고 많이 배웠으며 질문도 환영하는 느낌으로 받아들 주셨기에

길다면 길고 짧다면 짧았지만 얻어간게 정말 많았다.

지금도 질문을 하면 다들 들어주시더라

그렇게 해서 윗부분에 설명했던 테스트코드 와 같이 MybatisJPA

성공적으로 바꿨다.

쉘 스크립트 작성기

일단 지금 사용하는 스프링부트

이 프레임워크에는 내장톰캣이 구성되어있다.

근데도 과제를 수행하는 프로젝트에서 그 회사쪽의 요청으로 외장톰캣을 사용했다.

내장 톰캣이 있다고 말씀을 드렸지만 외장톰캣을 사용해야 한다고 그러시더라.

거기에 깃랩을 사용하여 소스관리를 하지만? 소스관리일뿐 그것을 가져와서 자동화는 따로 시키지 않더라.

이부분이 궁금했지만 그래도 외주를 받아서 우리가 과제를 진행했기 때문에 그쪽이 갑이어서 건의는 더이상 하지 않았던 기억이 있다.

일단 뭐 배포를 해야되는데 내가 없을 때는

프론트 개발자 한분이 전부 배포를 했다고 한다.

근데 배포하는 방식이

계속 그냥 콘솔에 cd xxx, sudo xxx, ...등등 일일이 타이핑을 치고계셔서 좀 놀랐다.

이 과정이 귀찮지는 않은가 여쭤보았고 여쭤보기도 전에 머릿속으로 당연히 번거롭고 귀찮다는걸

나도 느끼면서 질문했는데 당사자도 귀찮았다고 생각한다.

그래서 내가 할 수 있는 선에서의 최선이 바로 이 쉘스크립트 작성이었다.

이거로 인해서 반복되는 명령어 그리고 그것들을 하나하나 입력하는데에 대한 시간들에 대해

많이 줄였다. 정확하게 시간을 재지는 않았지만 빨라도 20초? 걸리던거 그냥

~: ./deploy.sh

이거만 시켜주면 되니까 이 명령어 치는데 얼마나 걸릴까???

생각은 읽는 사람의 몫이다.

뭐 이렇게 나름의 노력을 했더니 개발이 그냥 재미있다.

뭔가를 계속 찾아서 불편한 부분을 개선하는 나의 일련의 노력들 그리고 그걸 해냈을 때 희열감 그리고 그것에 대한 기억은 대단하다.

개월이 지날 수록 이런 회고글 좀 더 쓰는식으로 진행을 하겠다.

728x90

'Diary' 카테고리의 다른 글

블로그를 옮기고 최신 근황  (0) 2022.08.13
업무 리팩토링에 대한 회고  (0) 2022.08.10
1개월 1일 1커밋 회고  (0) 2022.08.07
TDD Clean Code with Java 12기 - 1주차  (0) 2022.08.05
728x90

첫 일기

코드는 깃허브에 있다.

CS bool 정리 와도 연관이 되지만, 좀 자유롭게 쓰고 싶어서

이렇게 일기 카테고리로 작성한다.

들어가면서

우선은 나와 같이 노력해주시는 창훈님과 밑바닥 컴퓨팅 시스템을 같이

오프라인 스터디로 진행하고 있다.

처음엔 둘다 멋대로 또는 자기가 머릿속으로만 생각했던 대로 nand2tetris를 구현했었는데, 진행하다 보니까

뭔가 제대로 잡히질 않았다..

태초마을로..

그래서 논리게이트 하나씩 알면서 그리고 진리표를 보았을 때, 어떤 게이트들을 써서 구현을 해야하는지..

그런 개념을 확립하고 머리로만 짜는게 아니라 삽질도 해가면서 논리식으로 표현하는게 목표였다.

그래서 2장을 진행하다가 다시 1장으로 돌아오게 되었다. ㅋㅋㅋㅋㅋ 근데 결과적으로 얻어간 지식이 더 많은것 같다.

이게 대학교 때 물론 내가 기계쪽이 전공이지만, 디지털 논리 회로라는 과목에서 했던것들이다.

주의깊게 보지 않았었을 뿐더러, 교수님이 강의해주실 때는 되게 재미가 없었고, 왜 배워야하는지 어디에 쓸 수 있는건지

그렇게 생각하며 무난하게 보냈던 과목인거같다.

새롭게 지금 CS지식을 학습하며 이 책에서 구현해야하는 조건들을 하나하나 카르노맵도 그려가면서,

또는 집합을 그려가면서 구현해보니까 이 진리표일땐, 이렇게 구현이 되는구나! 를 많이 느꼈던 것 같다.

일단 불대수 법칙에는 아래 이미지와 같은 법칙들이 명시되어 있다.

이건 수학을 배울때에도 봤던 기억이 있어서

그렇게 어렵지 않았다.

스크린샷 2021-10-24 오후 11 12 10

고생했던 자료의 흔적


논리식 부딪히기

KakaoTalk_Photo_2021-10-24-22-40-16

이부분은 처음에 논리식을 파헤치려 할 때 이해 안되는 부분 그리고 왜 그렇게 나오는지에 대해 설명하기 위해

밴-다이어그램을 그려가면서 설명하면서 의논을 했던 부분이다.

논리식 도출해보기

KakaoTalk_Photo_2021-10-24-22-40-00

어느정도 이해를 한 상태에서 진리표를 보고 집합으로 값을 도출하는 과정이다...

ㅋㅋㅋ 이렇게 정리하면서 보니까 안까먹겠다 싶더라 역시 쓰면서 대화도 해보고 팍팍 부딪히면서 학습하는게

기억에도 잘남고 동시에 보게되면 바로 아! 하고 깨닫게 되는 순간이 훨씬 많다는 사실..

정말 많이도 그렸고 단순한 And, Or 인데도 불구하고 애를 먹었다.

논리식을 도출할 때 a와 b에 해당하는 진리값을 곱해서 나온게 output인데 And, Or에 따라서
곱으로 도출하는것, 합으로 도출하는것 그 논리 합, 곱 이게 섞이면서 식을 몇번을 갈아 엎었다.

카르노맵을 생각해냈다!!!

KakaoTalk_Photo_2021-10-24-22-40-08

이제 머리로만 간소화해서 짜다가는 필요에 의해서 카르노맵 이 있다는걸 생각해냈고,

검색을 통해 2변수, 3변수, 4변수 등등의 카르노맵을 그리는 법,

그러면서 짝수개를 묶어서 값을 도출해낼 수 있다는 지식까지 습득한 채로 다시 논리식을 도출해보게 되었다.

결국 모양으로 쳐둔 것들이 최종 값인데 곱연산은 And, 합연산은 Or 이런식으로 '기호는 Not으로 해서
게이트를 연결해보았다.

그러니까 이해도 되면서 어떻게 동작하는지도 알겠고 너무 재밌더라 👍

이때부턴 탄력받아서 아래것들도 쭉쭉 진행했었다 🔥🔥🔥

2변수 카르노맵 간단 풀이

Y
X
0 1
0 0 1
1 1 1

Or의 진리표이다. 이 진리표가있을 때 짝수개는 인접한것 끼리 묶을 수 있다고 했다.

  • X가 1일때, Y값에 관계없는 경우 (Y, Y' 둘다 상관없다)
  • Y가 1일때, X값에 관계없는 경우 (X, X' 둘다 상관없다)

두가지로 도출해 볼 수 있다.

두가지는 + 로 연결이 된다.

그래서 Out = X + Y 가 되는 것이고 그래서 논리합 이라고 부르는 것이다❗️

이게 트이니까 정말 재밌어서 얼른 하나라도 더 빨리 풀어보려고 했던 것 같다.

KakaoTalk_Photo_2021-10-24-22-39-53

KakaoTalk_Photo_2021-10-24-22-39-43

KakaoTalk_Photo_2021-10-24-22-39-31

정리

아무튼 이런식으로 진행해서 재밌고 잘 이해되게 1장을 클리어한 것 같다.

다음 다이어리에선 반가산기, 전가산기 쪽을 다뤄보도록 하는 시간을 가져보겠다. 👏

뭔가 이렇게 풀이해내는 것이 읽는것도 읽는 맛이 나고 뭘 어떻게 했는지 보이게 되는것

그게 직관적이라 상당히 괜찮은것 같기도 하다. 물론 이미지 찍어서 업로드 하는것이 번거롭지만

그래도 또 어제의 나보단 한 층 더 성장했으니까 그거로 만족한다 😇

타인과 비교하지 않고 혼자 성장치를 잘 쌓다보면 언젠가는 주변에 좋은 개발자들과 어깨를 나란히 할 수 있는 날

그날이 올거라고 반드시 믿는다.

728x90

'CS' 카테고리의 다른 글

불 연산 회고  (0) 2022.08.09
불 논리 정리 2  (0) 2022.08.09
HTTP  (0) 2022.08.07
불 논리 정리  (0) 2022.08.07
728x90

여기서 나오는 모든 예제는 깃허브에 있다.

📌 변수

변수는 값을 저장하는 공간이다.

📌 변수란?


프로그래밍에서의 변수란, 값을 저장할 수 있는 메모리상의 공간이라고 한다.

이 공간에 저장된 값은 변할 수 있기 때문에, 변수라고 이름이 붙여졌다.

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

그렇기 때문에, 새로운 값을 저장하면 기존의 값은 날아가게 된다.

📌 변수의 선언과 초기화


📌 변수의 선언

변수의 선언 방법은

public class Class {
    int age; // age라는 이름의 변수 선언
    // int : 변수 타입
    // age : 변수 이름
}

변수 타입은 변수에 저장될 값이 어떤 타입인지를 지정해주는 것이다.

변수 이름 변수의 이름이다. 이 변수 이름 은 메모리 공간에 이름을 붙여주는 것이다.

int age; 메모리 주소지가 1이라고 가정했을 때,

int 타입의 age 변수를 1 주소지에 할당해라 가 되는 것이다.


📌 변수의 초기화

변수를 선언한 이후에는 변수를 사용할 수 있는데, 그전에 반드시 변수를 초기화 시켜주어야 한다.

메모리는 여러 프로그램이 공유하기 때문에, 다른 프로그램에 의해 그 메모리가 알 수 없는 값이 들어있을 수 있기 때문에

반드시 초기화를 해주어야 한다.

여기서 연산자가 나오는데 바로 대입 연산자(=) 이다.

이 대입연산자로 변수에게 값을 할당해줄 수 있다.

int age = 26 → 변수 age를 선언하고 26으로 초기화 시켰다.

같은 타입이라면

int a;
int b;
int x = 0;
int y = 0;

//같은 코드
int a, b;
int x = 0, y = 0;

하지만 코딩 컨벤션은 한줄에 하나를 할당하는게 대부분의 규칙처럼 정형화 되어있다.

이 부분에 대해선 협업하는 사람들에 따라 갈리겠지만 보통의 개발자들은 전자를 선호할 것이다.

변수의 초기화란, 변수를 사용하기 전에 처음으로 값을 저장하는 것

@Test
void test() {
    int year = 0;
    int age = 21;

    year = age + 2000; //변수 age + 2000
    age += 1; //age 저장된 값 1증가

    assertThat(year).isEqualTo(2021);
    assertThat(age).isEqualTo(22);
}

대입 연산자는 바로 수행되는 것이 아니라, 우변에 모든 계산이 끝난 후에 할당을 진행한다.

메서드 안에서 변수를 초기화하는 경우엔 명시적으로 int a = 0; 이렇게 초기화를 진행해주지만,

클래스 변수 즉, 전역변수는 int a; 이렇게 선언만 해주더라도 int 타입에 String을 넣는다거나

혹은 String 타입에 int를 넣는

참사를 방지하기 위해 컴파일러에서 아래에 출력한 0, null처럼 자동으로 값을 할당해 준다.


📌 두 변수의 값 교환하기

너무 유명한 swap 예제이다. CallByValue, CallByReference

조금 원초적으로 책에서는 설명되어있는데,

int a = 10;
int b = 20;

두 값을 서로 바꾸려고 할 때, b에 저장된 값을 a에 해버리면 둘다 20이 될 것이다.

그러기에 중간 변수를 하나 두어 스왑을 해주어야 한다.

int a = 10;
int b = 20;
int temp = 0;

temp = a;
a = b;
b = temp;

이렇게 해서 값을 바꿔주어야 한다.


📌 변수의 타입

값은 크게 문자, 숫자 두가지 부류로 나눌 수 있다.

숫자는 또 실수와 정수로 나뉜다.

이런 값의 종류에 따라서 값이 지정될 공간의 크기, 저장형식을 정의한 것이 자료형이다.

이 자료형에는 문자형(char),정수형(byte, short, int, long), 실수형(float, double) 등이 있다.

저장하려는 값의 특성에 따라 알맞은 자료형을 맞춰주면 된다.

📌 기본형과 참조형

  • 기본형
    • 변수는 값을 실제 값을 저장
    • boolean, char, byte, short, int, long, float, double
  • 참조형
    • 값이 저장되어 있는 주소를 값으로 가짐
    • 8개의 기본형을 제외한 나머지 타입

변수 타입에 대한 정리는 여기

📌 상수와 리터럴

상수(constant)는 말 그대로 변하지 않는 값. 그래서 변수 앞에 final을 붙여주면 된다.

final은 선언과 동시에 무조건 초기화를 해주어야하며, 그 이후엔 변경할 수 없다.

static 키워드도 같이 붙여주게 되는데,

붙이는 이유는 어떠한 객체에 final 변수가 하나 있다면 그 객체를 생성할 때마다,

final변수는 생기게 된다. 하지만 static 을 사용해서 메모리에 적재하게 두면 1개의 변수만이 여러개의 클래스에서 공유하게 되는 것이다.

이 상수를 쓰는 이유는 나는 2가지라고 생각한다.

첫째, 메서드안에 연산을 수행할 때, 하드 코딩 으로 숫자를 집어넣게 되면 무슨일을 하는 숫자인지 모를 수 있다.

그렇기에 상수로 떼어내어서 어떤 역할을 하는 변수인지 의미있게 이름을 준다.

둘째, 반복되는 숫자를 상수로 도출하면 반복코드를 제거할 수 있고, 들어가 있던 값을 상수만 바꿔주면

수정작업도 용이하기 때문이라고 본다.

📌 형변환

캐스팅(casting) 이라고도 부르며 서로 다른 타입간의 연산을 수행할 때,

같은 타입으로 변환시켜주는 것이 바로 형변환이다.

변수나 리터럴 앞에 변환하고자 하는 타입을 명시해주면 변환이 된다.

(타입)피연산자

기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환이 가능하다.

하지만 기본형과 참조형간의 형 변환은 불가능하다.

그리고 기본형 타입에서도 작은 값을 큰값으로 그러니까 int형 변수를 long 자료형에 넣는다고 한다면

자동 형변환이 일어나게 된다.


2021-11-06 추가 업데이트

자바 공식문서 페이지를 보면서 추가적으로 여러개를 더 정리해보았다.

📌 변수의 종류

📌 인스턴스 변수 (비정적 필드)

static 키워드 없이 선언된 필드에 저장한다.

해당 값이 클래스의 각 인스턴스(각 개체마다)에 고유하기 때문에 인스턴스 변수라고 한다.

📌 클래스 변수(static 필드)

이 변수는 클래스가 인스턴스화 된 횟수에 상관없이 정확히 한개만 있음을 컴파일러에게 알려준다.

static은 초기화 후에 변경되지 않게 하려고 final을 같이 붙여서 사용해준다.

📌 지역 변수

객체가 필드에 상태를 저장하는 방식과 유사하게, 메서드는 임시 상태를 지역변수에 저장한다.

지역변수는 선언된 메서드에서만 볼 수 있다. 나머지 클래스에서는 액세스 불가능

📌 매개변수

흔히 보던 main메서드

public static void main(String[] args){} 에서 args가 바로 매개 변수이다.

매개변수는 항상 필드 가 아닌 변수 로 분류된다는 것이다.

728x90

'Java' 카테고리의 다른 글

변성  (0) 2022.08.11
일급 컬렉션  (0) 2022.08.09
상태 패턴 적용  (0) 2022.08.07
프로젝트 리팩토링  (0) 2022.08.07
728x90

쿼리 속도 개선

업무중 엄청 느린 쿼리들이 여럿 있었다.

그냥 단순히 select * from 으로 모든 칼럼을 조회하는 것이 아니라

조건에 맞는 데이터를 뽑는 로직들이 있었는데

일단 복합키로 PK가 잡혀있는 상황이고, 세개의 복합키들 중에 두개는 중복되는게 많았다.

다시 말해 카디널리티가 낮은 것 들이었다.

JPA를 사용해서 더럽게 뽑아온 다음에 가공하려고 했었지만, 데이터가 많아서 그것조차 조금 어려운 상황이었다.

계속 똑같은 쿼리문을 반복적으로 실행시키니까 처음 사용자입장에선 빨리 받아오는 것처럼 느낄지 모르겠다 (근데 이것도 느리다.)

하지만 맨 뒤쪽에 와서 이 쿼리를 실행하게 된 사람은 앞 사람들이 요청한 그 트랜잭션들이

처리된 후에나 실행이 되기 때문에 쿼리가 1초이고 누른 사람이 10명이라면

마지막 사람은 10초보다 그 이상이 걸려서 데이터를 받아볼 수 있게 된다.

이게 얼마나 흉측한 상황인지 10명만 해도 이정도로 지연된다는 것 자체가 웃기다.

개선 방법

우선은 DB 실행계획을 보았다.

explain select ...

이 구문으로 실행계획을 찾아봤다.

나는 인덱스를 생성하는 방식으로 쿼리 개선을 진행하였다.

블로그 상에 있던 규칙을 가져왔다.

쿼리 최적화를 위한 7가지 체크리스트 에서 내용을 좀 추려봤다.

요약해보자면

SELECT시에는 꼭 필요한 칼럼만 불러와야 한다.

(결국 조건에 맞는 데이터를 줄 단위로 가져온 후 거기서 추출하고 싶은 각 칼럼을 도출해 내는것이니까 메모리적으로는 이득일 수 있다.)

  1. 조건을 부여할 시에는 가급적이면 DB에 별도의 연산을 끼워넣지 않는다.
  2. LIKE 사용 시, 와일드카드 문자열(%)String 앞부분에 배치하지 않는 것이 좋다.
  3. SELECT DISTINCT, UNION DISTINCT 같은 중복 값을 제거하는 연산은 최대한 사용하지 않아야 한다.
  4. 쿼리 실행 순서는 WHERE절이 HAVING절보다 먼저 실행된다. WHERE절로 데이터를 작게 가공해둔다면 효율적인 연산이 가능하다.
  5. 3개 이상의 테이블을 JOIN할 경우에 크기가 가장 큰 테이블을 FROM절에 배치하고 JOIN절에는 남은 테이블을 작은 순서대로 배치하는 것이 좋다.
  6. 자주 사용하는 데이터의 형식에 대해서는 미리 전처리된 테이블을 따로 보관 or 관리하는 것도 좋다.

일단 이중에 해당하는 사항은 1, 2번을 사용한 쿼리인데
1번은 바람직하게 잘 실행했다.

하지만 2번에서 WHERE조건이 조금 복잡하게 구성이 되어있었다.

애시당초에 조회속도가 그냥 느려서 조건을 검색하여도 느렸다.

그러니까 복합키 중에 두 키가 같은 값으로 쭉 정제가 되어있었기 때문에

카디널리티가 높은 (그러니까 중복 값이 적은) 칼럼을 인덱스를 잡아주어 스캔을 하도록 유도하려고 했다.

실행 계획

image

실행 계획에는 위와 같이 구성이 되어있다.

실행 계획에 대한 설명이 필요하다면 여기에서 확인 가능하다.

해결

그래서 나는 카디널리티가 높은 칼럼을 찾아야 했는데 복합키중 1개면서 동시에 유니크한 그런 데이터 칼럼이 바로 날짜였기 때문에 이 칼럼에 인덱스를 부여해주었다.

CREATE INDEX 해당칼럼별명
on 테이블 (인덱스칼럼);

부여해준 후

그렇게 해서 쿼리 테스트를 진행했다.

결과는 아래와 같다.

개선 전

느린쿼리

개선 후

개선쿼리

시간을 정말 많이 줄이게 되었다.

728x90

'DB' 카테고리의 다른 글

[DB] 옵티마이저  (0) 2022.08.05

+ Recent posts