오늘은 실시간 강의가 오전 9시에 한 번 오후 7시에 한 번 있었다. 둘 다 지각을 했는데 오전에는 준비는 일찍했으나 피를 보는 바람에 그거 처치한다고 늦었고 오후에는 중간에 나가 링겔을 맞고 왔더니 그 탓인지 졸려서 잠드는 바람에 늦고 말았다.
오전 수업에서는 튜터님이 객체들 간의 소통? 협력? 을 설명해주신다고 실시간으로 카페 시스템을 간단하게 짜서 보여주셨는데 객체에는 최소한의 책임과 역할을 주는게 좋다는 말씀이 직접 보니 이해가 잘 되었다. 물론 나한테 첨부터 짜보라 하면 그렇게 잘 짤 자신은 없지만 어떤 느낌인지 안게 중요하니까!
그리고 클래스의 변수는 final 키워드를 붙여주고 나중에 값 변경이 필요할 때 풀면 된다고 하셨는데 나는 이걸 상수화 시켜주라는 의미로 알아들었는데 저녁에 개발자인 고딩 때 친구와 서로 말을 하다 그 친구도 다 상수화 시키면 메모리 괜찮나...? 해서 둘이 찾아보니 자바는 final 앞에 static을 붙여주면 상수화 시켜준다는 의미고 그냥 final은 한 번만 초기화 가능하다는 의미더라. 이렇게 또 하나 배워간다.
오후 강의는 CS 특강이었는데 프로세스, 쓰레드, 비동기에 대해 배웠는데 한 시간 특강에 앞 부분을 3분의 1정도 날려 먹는 바람에 정신이 멍했는데 첨부터 들은 분들도 잘 이해를 못하셔서 zep으로 돌아간 후에 튜터님이 보충수업을 해주셨다.
프로세스는 각 프로그램들이 올라가는 공간이고 쓰레드는 프로세스 안에 있는 프로세스와 같은 역할을 하는? 그런 아이인데 프로세스와 쓰레드의 차이점은 프로세스 간에는 서로 대화? 가 불가능하지만 쓰레드는 서로 소통하는 것이 가능하다는 것이다.
비동기에 대해서는 일단 답을 해주고 뒤에서 실행을 하는 것이라고 하는데 실패하면 어떡하나 여쭤봤더니 비동기의 책임은 나이기 때문에 성공할 때까지 반복작업을 해서 어떡해든 성공을 돌려줘야한다 하셨다.
이후에 위에서 말한 개발자인 친구와 대화를 하다보니 이런저런 말이 나왔는데 비동기는 순서 보장이 안 된다고 한다. 튜터님이 카페를 예시로 들어주셔서 그 말을 하다가 얼마 전 친구가 동기식으로 일을 하시는 직원이 있는 카페를 봐서 다들 충격 먹었다 라고 했는데 그 이후에 나온 대화들이 동기식과 비동기식을 이해하는데 도움이 될 거 같아 적어본다.
첫 날 친구가 카페에 갔을 때 카페에 직원 한 분이 일을 하시는 방식이 한 분의 주문을 받고 그 분의 음료를 만들어 내가고 다음분의 주문을 받고 음료를 만들어 나가는 말 그대로 동기식으로 처리를 하셨는데 다음 날 가보니 직원 한 분이 더 오셨더란다.
그래서 동기식 비동기식을 이야기 하고 있었기 때문에 내가 그럼 그게 비동기식 처리인건가 한 분이 주문 계속 받고 뒤에서 다른 한 분이 만들어서 순서대로 나가는? 이라고 말했더니 친구가 말하길 비동기식은 순서보장이 안 되서 순서보장을 해주려면 따로 처리를 해줘야하는 것으로 알고 있단다.
그래서 그럼 실제 카페처럼 커피만 있거나 커피 한잔이라 먼저 만들어진 건 뒷번호여도 먼저 나가고 프라페 같은 건 만드는데 시간이 걸리니까 완성되면 그 때 나가고 이런게 비동기식인건가? 라고 했더니 본인이 하려던 말이 그거라고 한다.
그리고 블록과 논블록에 대해 동기 분이 올려주신 이미지를 친구한테 보내주니 친구가 카페에 대입해서 말해준게 블록은 손님이 주문을 하고 앞에서 대기하는 느낌이고 논블록은 주문을 한 후 어디 자리로 가서 자기 할 일을 하는 느낌이라고 해줬다.
튜터님과 친구 덕에 어느 정도 개념은 잡힌 느낌이었다.
그리고 오늘도 역시 나는 프로그래머스 코딩테스트를 푼다. 병원 갔다오고 잔다고 튜터님이 내주신 숙제도 못 했는데 이거 다 하고 잘 수는 있을까....
세균 증식
def solution(n, t): answer = 0 for i in range(t): n *= 2 answer = n return answer
세균이 1시간에 2배씩 증가할 때 n개의 세균과 t시간이 주어질 때 세균의 값을 구하라는 문제였다.
for문을 한 줄로 써보려니 배열로 저장이 되서 다른 건 생각이 나지 않아 위와 같이 코딩을 했는데 지금보디 처음 answer를 n으로 초기화 시키고 거기에 *= 2를 해주면 됐는데 괜히 코드 수만 더 늘렸다. 물론 아래에 다른 분이 푼 풀이는 넘사벽이었지만....
def solution(n, t):
return n << t
<<은 비트단위쉬프트연산이라고 하는데 이 연산은 정수를 2배로 곱하거나 나눌 때 사용한다고 한다. 컴퓨터 내부는 이진법으로 이루어져 있기 때문에 <<을 해주면 2를 곱하고 >>를 해주면 2를 나누는 거라는 걸 아주 잘 이해할 수 있었다. 저렇게 뽑아내는 능력은 없지만...
제곱수 판별하기
def solution(n): answer = 0 num = 0 while 1: num += 1 if num**2 == n: answer = 1 break if num**2 > n: answer = 2 break return answer
n이 어떤 자연수의 제곱수라면 1을 아니라면 2를 반환하는 문제였다. while문은 얼마만큼 반복해줘야할지 모를 때 사용하며 탈출조건을 확실히 써줘야한다고 해서 저렇게 작성했다.
능력자분들은 확실히 다르더라 if문의 삼항 연산자를 쓰면 됐는데 왜 생각을 못했을까?
def solution(n):
return 1 if (n ** 0.5).is_integer() else 2
**연산자는 제곱을 해준다는 뜻이다. 이걸 보고 아 수학적 지식도 어느 정도 필요하구나 싶었던게 **0.5는 2분의 1 제곱을 해주겠다는 뜻이기 때문에 만약 n이 어떤 자연수의 제곱수라면 그 자연수의 값이 나올거고 아니라면 소수점이 나오며 그 판별을 is_integer()로 해준 코드였다. 만약 정수라면 is_integer()는 true를 반환하고 아니라면 false를 반환하기 때문에 저런식의 삼항 연산자 사용이 가능하다는 걸 알았다.
문자열안에 문자열
def solution(str1, str2): return 1 if str2 in str1 else 2
문자열 str1안에 str2가 있다면 1을 반환하고 없다면 2를 반환하라는 문제였다. 바로 위에 삼항 연산자를 이용한 식을 봤기 때문에 응용해서 풀었다. 다른 분들 역시 좋은 코드들은 이런식으로 짜져있어 이번 문제는 가져오지 않았다. 그 김에 in 연산자에 대해 찾아보았다.
in과 not in 연산자는 포함 확인 연산자로 가지고 있는 데이터 안에 원하는 데이터 값이 있는지 없는지 확인하기 위한 연산자로 결과는 bool 타입으로 반환되고 in과 not in은 질문부터가 포함 되었니? 와 포함되지 않았니? 이기 때문에 포함되었다면 in은 true로 not in은 false로 그 결과값이 반대로 나타난다.
in의 경우 사용 범위는 2종류로 리스트, 문자열, 튜플, 딕셔너리에 값이 존재하는지 확인하는 용도와 for문에서 in 뒤에 있는 값에서 요소들을 하나씩 뽑아와 앞의 값에 넣어주는 용도로 사용한다. 고 다른 블로그에서 설명했지만 이 경우는 기호만 같지 의미가 다르니 not in 과 in에 대해 설명할 때 가져오기엔 좀 명확하지 않지 않나 라는 생각이 들었지만 그냥 공부할 겸 가져왔다. 헷갈리지만 않으면 되니까.
그리고 in과 not in은 대소문자를 구분한다고 한다. 어쩌면 당연한 걸지도?
OX 퀴즈
def solution(quiz): answer = [] for i in range(len(quiz)): result = quiz[i].split(" ") if result[1] == "-": if int(result[0]) - int(result[2]) == int(result[4]): answer.append("O") else: answer.append("X") else: if int(result[0]) + int(result[2]) == int(result[4]): answer.append("O") else: answer.append("X") return answer
X 연산자 Y = Z 형태의 문자열이 배열로 저장됨 Quiz가 매개 변수로 들어올 때 그 수식이 옳다면 O를 틀리다면 X를 배열로 저장해 출력해주는 문제로 연산자에는 더하기와 빼기만 들어갈 수 있다는 문제였다. 연산 기호와 숫자 사이에는 항상 공백이 존재하며 음수를 표시하는 마이너스와 숫자 사이에는 공백이 존재하지 않는다는 제한사항이 있었다.
통과는 했는데 풀면서도 이거 그냥 어거지로 푸는 중인데 싶었다. 처음에 if문에 있는 result를 int로 타입 변환해주지 않았더니 str은 연산을 할 수 없다고 오류가 떠 거기서 다 int로 바꿔주면서 또 이건 아닌 것 같은데 했다.
def valid(equation):
equation = equation.replace('=', '==')
return eval(equation)
def solution(equations):
return ["O" if valid(equation) else "X" for equation in equations]
다른 분의 풀이 방식이다. 문자열을 나누는 함수를 따로 두고 for문을 돌리며 함수를 호출해서 참 거짓을 판단하는 식인데 처음에 한줄로 if문을 쓰고 for문을 써보고 싶어 고민을 했던 방향이 틀리지 않았음을 확인해서 기뻤던 것 갔다. 쓰다보니 너무 길어져서 결국 위 같이 되버린데다 나는 삼항 연산자의 조건 부분에 for문을 넣으려 했는데 그게 아니라 한 줄 for문의 연산 부분에 삼항연산자를 둬야하는거였다.
그리고 나는 split를 써 띄어쓰기를 기준으로 잘라 배열로 저장시켜서 int 형으로 변환시키는 과정이 필요했는데 다른 분들은 아예 valid라는 함수를 만들어 그 안에서 replace로 문자열에서 = 를 ==로 변환시켜주고 문자열로 연산을 받으면 결과값을 반환해주는 eval함수를 return 해주어 참이면 O 거짓이면 X를 반환시키는 식으로 코드를 구현하셨다.
오늘의 TIL은 여기까지 튜터님이 내주신 자바 숙제를 하다가 자야겠다.