728x90
반응형

비트연산자를 쓸 수 있느냐를 물어보는 문제이다. 처음에는 그냥 bin을 써서 풀었는데,

확실히 비트연산자 쓰는 게 훨씬 편한 것 같다. 

 

풀이 1

def binary(num, n):
    b = bin(num)[2:]
    return (n - len(b))*'0' + b

def str_sum(n, s1, s2):
    s = ''
    for i in range(n):
        s += '#' if s1[i] == '1' or s2[i] == '1' else ' '
    return s

def solution(n, arr1, arr2):
    ans = [0]*n
    for i in range(n):
        ans[i] = str_sum(n, binary(arr1[i], n), binary(arr2[i], n))
    return ans

 

풀이 2 

비트연산자와 replace를 사용하니 훨씬 쉽게 풀린다

def solution(n, arr1, arr2):
    ans = []
    for i in range(n):
        b = bin(arr1[i] | arr2[i])[2:]
        ans.append((n - len(b))*' ' + b.replace('1', '#').replace('0', ' '))
        
    return ans
728x90
반응형
728x90
반응형

그냥 조건문(노가다), DFS, BFS 등의 방식으로 풀 수 있는 문제이다.

나는 BFS 알고리즘을 사용해서 풀었다.

place에 map함수를 쓴 이유는 place가 문자열로 이루어진 리스트이기 때문이다.

예를 들어 place[0]이 문자열이라 place[0][0] = 'X'이 안된다. 그래서 쓰기 쉽게 map함수를 써서 리스트로 바꿔줬다.

 

풀이

1. place 탐색 -> place의 현재 위치가 'P'라면 'X'로 바꾸고 BFS 탐색 시작

2. BFS 탐색)

   상하좌우로 탐색하는데 맨 처음 탐색 시작 위치(i, j)와 다음 위치(Y, X)의 맨헤튼 거리가 2 이하일 경우에만 진행한다.

   다음 위치가 'O' 라면 현재 위치를 'X'로 바꾸고 계속 탐색 진행

   다음 위치가 'P'라면 거리 두기 위반이므로 바로 0 리턴

3. 한 명이라도 위반하면 0을 리턴해야 되므로 BFS 탐색이 끝날 때마다 check &= bfs(i, j) 같은 방식으로 check를 업데이트

4. 작은 반복문 끝날 때마다 ans에 check를 추가  

 
import sys
sys.setrecursionlimit(10000)

def solution(places):    
    def bfs(i, j):
        q = [(i, j)]
        while q:
            y, x = q.pop(0)
            for dy, dx in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                Y, X = y+dy, x+dx
                if 0 <= Y < 5 and 0 <= X < 5 and abs(Y-i) + abs(X-j) <= 2:
                    if place[Y][X] == 'O':
                        place[Y][X] = 'X'
                        q.append((Y, X))
                    elif place[Y][X] == 'P':
                        return 0
        return 1
    
    ans = []
    for place in places:
        place = list(map(list, place))
        check = 1
        for i in range(5):
            for j in range(5):
                if place[i][j] == 'P':
                    place[i][j] = 'X'
                    check &= bfs(i, j)
        ans.append(check)                       
                    
    return ans
728x90
반응형
728x90
반응형

문제에 맞는 자료구조를 생성하고 활용해야 하는 문제이다.

이 문제의 경우에는 Counter를 사용해서 쉽게 풀 수 있다.

주의해야 할 점이 스테이지에 도달한 사람이 없을 때인데 이를 따로 처리해주지 않으면 런타임 에러가 난다.

이거 때문에 조금 푸는데 시간이 걸렸다. 

 

풀이

1. 각 스테이지별 도달한 유저의 수를 담은 딕셔너리를 생성(Counter)

2. 각 스테이지별 실패율 계산

3. 실패율을 기준으로 내림차순 정렬한 리스트의 인덱스를 반환

from collections import Counter

def solution(N, stages):
    ans = []
    n = len(stages)
    counter = Counter(stages)
    for i in range(1, N+1):
        if n:
            ans.append(counter[i] / n)
            n -= counter[i]
        else:
            ans.append(0)
                
    return [i+1 for i in sorted(range(N), key=lambda x : ans[x], reverse=True)]
728x90
반응형
728x90
반응형

문제 상황에 맞는 적절한 자료구조를 생성하고 활용해야 되는 문제다. 

Collections의 Counter를 사용하면 상당히 쉽게 풀 수 있다. 처음에 안 쓰고 풀어서 그런지 쉽지 않았다. 

조합을 직접 구하기는 번거롭기에 itertools의 combinations 함수를 사용했다.

 

풀이 1 (Counter 사용 X)

*cource의 개수 만큼 반복([2, 3]의 경우 -> 2개짜리 조합, 3개짜리 조합 찾기)

1. 모든 order에서 가능한 n(cource 값)개 짜리 조합을 comb_li에 저장

2. comb_li에서 {주문된 개수: [메뉴1, ...], ... }의 형태의 딕셔너리 d를 생성

3. d에서 주문된 개수가 제일 많은 메뉴들을 ans에 추가

from collections import defaultdict
from itertools import combinations

def solution(orders, course):   
    ans = []
    for n in course:
        d = defaultdict(list)
        comb_li = []
        max_cnt = 0        
        for order in orders:
            if len(order) >= n:
                comb_li.extend(list(combinations(sorted(order), n)))
        
        for comb in set(comb_li):            
            cnt = comb_li.count(comb)
            d[cnt].append(''.join(comb))
            if cnt > max_cnt:
                max_cnt = cnt                
        
        if max_cnt > 1:
            ans.extend(d[max_cnt])

    return sorted(ans)

 

풀이 2 (Counter 사용 O)

Counter를 사용했기에 d 딕셔러니가 필요가 없다. d 딕셔너리를 생성하는데 필요했던 자잘한 코드들을 지우니 훨씬

코드가 간결해졌다.

from collections import Counter
from itertools import combinations

def solution(orders, course):   
    ans = []
    for n in course:
        comb_li = []
        for order in orders:
            comb_li.extend(list(combinations(sorted(order), n)))

        counter = Counter(comb_li)
        if counter and max(counter.values()) > 1:
            ans.extend([''.join(k) for k in counter if counter[k] == max(counter.values())])

    return sorted(ans)
728x90
반응형
728x90
반응형

문제 상황에 맞는 적절한 자료구조를 생성하고 활용해야 되는 문제다.

요즘 카카오 초반 문제 특징인 것 같은데, 이 문제의 경우에는 2개의 Dictionary를 사용했다.

python의 defaultdict를 거의 처음 사용해봤는데 꽤 좋은 것 같다.

dict의 메서드인 setdefault도 사용해봤지만 defaultdict 쪽이 조금 더 편한 것 같다.

 

풀이

1. 유저별 신고한 id를 저장하는 report_user_dict, 유저별 신고당한 횟수를 저장하는 report_cnt_dict를 생성한다.

2. 위의 두 사전을 사용해 유저가 신고한 id가 k번 이상인지 확인하고 카운트해준다. 

from collections import defaultdict

def solution(id_list, report, k):
    report_user_dict = defaultdict(set)
    report_cnt_dict = defaultdict(int)
    ans = []
    
    for arg in set(report):
        id, reported_id = arg.split()
        report_user_dict[id].add(reported_id)
        report_cnt_dict[reported_id] += 1
        
    for id in id_list:
        cnt = 0
        for reported_id in report_user_dict[id]:
            if report_cnt_dict[reported_id] >= k:
                cnt += 1 
        ans.append(cnt)
    
    return ans
728x90
반응형
728x90
반응형

간단한 구현 문제이다. 문제에서 정해준 순서대로 입력 문자열을 처리해주면 된다.

 

첫 번째 풀이  

리스트 사용

def solution(new_id):
    # 1
    new_id = new_id.lower()
    
    # 2
    li = [c for c in new_id if c.isalnum() or c in "-_."]
    
    # 3
    i = 0
    while i < len(li)-1:
        if li[i] == li[i+1] == '.':
            li.pop(i)
        else:
            i += 1
    
    # 4
    if li and li[0] == '.':
        li.pop(0)
    if li and li[-1] == '.':
        li.pop()
    
    # 5
    if li == []:
        li.append('a')
    
    # 6
    if len(li) >= 16:
        li = li[:15]
        if li[-1] == '.':
            li.pop()
    
    # 7
    if len(li) <= 2:
        while len(li) < 3:
            li.append(li[-1])
    answer = ''.join(li)
    
    return answer

 

두 번째 풀이

리스트를 생성할 필요가 있을까 싶어서 문자열로도 풀어봤다.

def solution(new_id):
    ans = ""

    # 1
    new_id = new_id.lower()
    
    # 2
    for c in new_id: 
        if c.isalnum() or c in "-_.":
            ans += c
    
    # 3
    while ".." in ans:
        ans = ans.replace("..", '.')
    
    # 4
    if ans and ans[0] == '.':
        ans = ans[1:]
    if ans and ans[-1] == '.':
        ans = ans[:-1]
    
    # 5
    if ans == '':
        ans = 'a'
    
    # 6
    if len(ans) >= 16:
        ans = ans[:15]
        if ans[-1] == '.':
            ans = ans[:-1]
    
    # 7
    while len(ans) < 3:
        ans += ans[-1]
        
    return ans
728x90
반응형
728x90
반응형

문제 상황에 맞는 적절한 자료구조를 생성하고 활용해야 되는 문제다.

카카오 코딩테스트 초반 문제들 특징인 것 같다. 

나름 잘 풀었다고 생각했으나 훨씬 좋은 풀이가 있었기에 두 번째 풀이를 추가했다.

 

풀이 1

record를 따라 유저의 id와 이름을 기록한 딕셔너리인 user_dic, 유저 id와 출력돼야 하는 메시지들이 담긴

리스트인 msg_li를 만들어줬다. 아래와 같은 느낌이다.

msg_li에서 메시지 부분을 유저 id에 매칭 되는 이름으로 수정한 결과를 담은 리스트를 반환해주면 끝이다.

-> [msg.replace(user_id, user_dic[user_id]) for user_id, msg in msg_li]

def solution(records):
    user_dic = {}
    msg_li = []

    for record in records:
        li = record.split()
        if li[0] == "Enter":
            command, user_id, user_name = li
            user_dic[user_id] = user_name
            msg_li.append([user_id, f"{user_id}님이 들어왔습니다."])
        elif li[0] == "Leave":
            command, user_id = li
            msg_li.append([user_id, f"{user_id}님이 나갔습니다."])
        else:
            command, user_id, user_name = li
            user_dic[user_id] = user_name
    
    ans = [msg.replace(user_id, user_dic[user_id]) for user_id, msg in msg_li]
    
    return ans

 

풀이 2

지금 첫 번째 반복문을 보면 Enter와 Change의 경우일 때 중복인 코드가 있는데,

이유는 내가 굳이 필요 없는 자료구조인 msg_li를 생성하고 msg_li를 통해 ans를 완성하려고 했기 때문이다.

msg_li를 생성하지 않고, 그냥 user_dic을 첫 반복문에서 완성하고 두 번째 반복문에서 바로 ans를 완성하면 된다.

위의 방식으로 짠 결과 코드가 훨씬 간단해졌다. printer는 두 번째 반복문에 조건문을 넣기 싫어서 만들었다.

def solution(records):
    user_dic = {}
    printer = {"Enter": "님이 들어왔습니다.", "Leave": "님이 나갔습니다."}
    ans = []
    
    for record in records:
        li = record.split()
        if li[0] in ["Enter", "Change"]:
            user_dic[li[1]] = li[2]

    for record in records:
        li = record.split()
        if li[0] != "Change":
            ans.append(user_dic[li[1]] + printer[li[0]])
            
    return ans
728x90
반응형
728x90
반응형

단순한 구현 문제이다. 

 

풀이

1. 0의 개수, 일치하는 숫자의 개수를 센다.

2. 0의 개수 + 일치하는 숫자 -> 순위가 제일 높은 경우, 일치하는 숫자 -> 순위가 제일 낮은 경우

이므로 이에 맞게 순위를 반환해준다.

def solution(lottos, win_nums):
    zero_cnt = lottos.count(0)
    matching_num_cnt = sum([n in win_nums for n in lottos])
    rank = [6, 6, 5, 4, 3, 2, 1]
    
    return rank[zero_cnt+matching_num_cnt], rank[matching_num_cnt]
728x90
반응형
728x90
반응형

스택을 사용하면 쉽게 풀 수 있는 간단한 구현 문제이다.

뭔가를 차곡차곡 쌓고 마지막에 쌓은 것부터 처리해야 되는 식의 문제 -> 스택을 생각하자

 

풀이

1. 인형을 뽑을 때마다 인형을 스택에 추가

2. 스택의 길이가 2 이상일 때 맨 뒤에 있는 인형 2개가 같으면 제거해야 하므로 stack pop 2번 후 ans += 2를 해준다. 

def solution(board, moves):
    ans = 0
    stack = []
    for m in moves:
        for i in range(len(board)):       
            if board[i][m-1]:
                stack.append(board[i][m-1])
                board[i][m-1] = 0

                if len(stack) > 1:
                    if stack[-1] == stack[-2]:
                        stack.pop(); stack.pop()
                        ans += 2
                break
                
    return ans
728x90
반응형
728x90
반응형

풀이

파이썬 내장함수 replace를 사용하면 아주 쉽게 풀 수 있다.  

def solution(s):
    li = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
    for i in range(10):
        s = s.replace(li[i], str(i))
    
    return int(s)
728x90
반응형
728x90
반응형

전에는 알고리즘 문제를 설렁설렁 어떻게든 풀기만 하는 느낌으로 넘어갔었는데, 이번에는 다시 공부한다는 생각으로

프로그래머스 문제들을 풀어보려고 한다.

클린코드도 복습하는 겸 나름 최대한 보기 좋게 짜보려고 한다.

 

풀이)

1. 거리를 구하기 위해서 우선 1: [0,0], 2:[0, 1] ... 9:[2, 2], 0:[3, 1]과 같이 숫자를 좌표로 변환해준다.

 2. 숫자와 왼손, 오른손과의 거리를 구한다.

3. 그 이후는 각 상황에 맞게 ans에 'L', 'R'을 더하고 왼손과 오른손의 위치를 업데이트해주면 된다.

1, 4, 7 -> 왼손, 3, 6, 9 -> 오른손, 2, 5, 8, 0 -> 왼손과 오른손 중 가까운 손

def get_idx(n):
    n = 10 if n == 0 else n-1
    
    return [n//3, n%3]

def get_distance(n1, n2):
    d1, d2 = get_idx(n1), get_idx(n2)
    d = abs(d1[0] - d2[0]) + abs(d1[1] - d2[1])

    return d
    
def get_nexthand(left, right, num, hand):
    if num in [1, 4, 7]:
        return 'left'
    elif num in [3, 6, 9]:
        return 'right'
    else:
        dl = get_distance(left, num)
        dr = get_distance(right, num)
        if dl < dr:
            return 'left'
        elif dl > dr:
            return 'right'
        elif dl == dr:
            return hand
    
def solution(numbers, hand):    
    left, right = 10, 12
    ans = ''
    
    for num in numbers:
        nexthand = get_nexthand(left, right, num, hand)
        if nexthand == "left":
            left = num
            ans += 'L'
        else:
            right = num
            ans += 'R'
    
    return ans
728x90
반응형
728x90
반응형

TIL (Today I Learned)

2022.03.08

오늘 읽은 범위

10장 클래스

책에서 기억하고 싶은 내용을 써보세요.

  • 클래스는 작아야 한다! -> 간결한 이름이 떠오르지 않는다면 클래스 필경 클래스 크기가 너무 커서 그렇다 (p.172)
  • 단일 책임 원칙(Single Responsibility Principle,  SRP) -> 클래스나 모듈을 변경할 이유는 하나뿐이어야 한다 (p.175)
  • 응집도(Cohesion) (p.177)
    클래스는 인스턴스 변수 수가 작아야 한다. 각 클래스 메서드는 클래스 인스턴스 변수를 하나 이상 사용해야 한다.
    일반적으로 메서드가 변수를 더 많이 사용할수록 메서드와 클래스는 응집도가 높다. 응집도가 높다는 말은 클래스에 속한 메서드와 변수가 서로 의존하며 논리적인 단위로 묶인다는 의미이기에, 우리는 응집도가 높은 클래스를 선호한다. 
  • 함수를 작게, 매개변수 목록을 짧게라는 전략을 따르다 보면 때때로 몇몇 메서드만이 사용하는 인스턴스 변수가
    많아지는데, 이는 새로운 클래스로 쪼개야 한다는 신호이다. 응집도가 높아지도록 변수와 메서드를 적절히 분리해 새로운 클래스 두세 개로 쪼개도록 하자 (p.178)
  • 개방-폐쇄 원칙(Open-Closed Principle, OCP) -> 클래스는 확장에 개방적이고 수정에 폐쇄적이어야 한다 (p.188)
  • 의존관계 역전 원칙(Dependency Inversion Principle, DIP) -> 클래스는 상세한 구현이 아니라 추상화에 의존해야 한다

 

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

이번 10장은 응집도 관련된 내용을 제일 재미있게 읽었던 것 같다. 변수, 메서드, 클래스의 응집도를 생각하면서

클래스를 구현해본 적도 없었고, 변수와 메서드의 응집도를 높일수록 클래스가 작게 쪼개질 수밖에 없겠구나라는

생각이 들었기 때문이다. 이 책을 읽으면 읽을수록 학습한 내용들을 바탕으로 코드를 짜고 싶다는 생각이 계속 든다.

스프링 공부를 좀 더 빠르게 해서 프로젝트를 진행해봐야겠다. 

728x90
반응형

'책 리뷰 > 클린코드' 카테고리의 다른 글

9장 단위 테스트  (0) 2022.03.06
7장 오류 처리  (0) 2022.03.04
6장 객체와 자료구조  (0) 2022.03.01
5장 형식 맞추기  (0) 2022.03.01
4장 주석  (0) 2022.02.27
728x90
반응형

TIL (Today I Learned)

2022.03.06

오늘 읽은 범위

9장 단위 테스트

책에서 기억하고 싶은 내용을 써보세요.

  • TDD 법칙 세 가지
    - 첫째 법칙: 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
    - 둘째 법칙: 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
    - 셋째 법칙: 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
  • 테스트 코드는 실제 코드 못지않게 중요하다 -> 테스트 코드가 복잡할수록 실제 코드를 짜는 시간보다 테스트 케이스를 추가하는 시간이 더 걸리기 십상이다 (p.156)
  • 테스트는 유연성, 유지보수성, 재사용성을 제공한다 -> 테스트 케이스가 있으면 변경이 쉬워지기 때문이다 (p.157)
  • 테스트 코드도 가독성이 좋아야 한다. 어쩌면 가독성은 실제 코드보다 테스트 코드에 더더욱 중요하다 (p.158)
  • 이중 표준 -> 실제 환경에서는 절대로 안 되지만 테스트 환경에서는 전혀 문제없는 방식이 있다. 대게 메모리나 CPU 효율과 관련 있는 경우다. 코드의 깨끗함과는 철저히 무관하다 (p.164)
  • 개념 당 assert 문 수를 최소로 줄여라 -> 때로는 함수 하나에 여러 assert 문을 넣을 수도 있지만, assert문 개수는 최대한 줄이는 것이 좋다 (p.165)
  • 테스트 함수 하나는 개념 하나만 테스트하라 (p.166)
  • 깨끗한 테스트는 F.I.R.S.T 규칙을 따르는데
    - 빠르게(Fast): 테스트는 빨라야 한다.
    - 독립적으로(Independent): 각 테스트는 서로 의존하면 안 된다.
    - 반복 가능하게(Repeatable): 테스트는 어떤 환경에서도 반복 가능해야 한다.
    - 자가 검증하는(Self-Validating): 테스트는 부울 값으로 결과를 내야 한다.
    - 적시에(Timely): 테스트는 적시에 작성해야 한다.

 

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

아직 자바로 테스트를 해본 적이 없어서 이해가 잘 되지는 않았다만, 다음에 테스트를 공부하게 된다면 지금 본 

내용이 학습에 큰 도움이 될 것 같다는 생각이 들었다.

728x90
반응형

'책 리뷰 > 클린코드' 카테고리의 다른 글

10장 클래스  (0) 2022.03.08
7장 오류 처리  (0) 2022.03.04
6장 객체와 자료구조  (0) 2022.03.01
5장 형식 맞추기  (0) 2022.03.01
4장 주석  (0) 2022.02.27
728x90
반응형

TIL (Today I Learned)

2022.03.04

오늘 읽은 범위

7장 오류 처리

책에서 기억하고 싶은 내용을 써보세요.

  • 오류 코드보다 예외를 사용하라 -> 논리가 오류 처리 코드와 뒤썩이지 않으므로 호출자 코드가 깔끔해진다 (p.130)
  • Try-Catch-Finally 문부터 작성하라 -> try블록에서 무슨 일이 생기든 호출자가 기대하는 상태를 정의하기 쉬어진다(p.132)
  • 미확인(unchecked) 예외를 사용하라 -> 확인된 예외를 사용할 경우, 하위 단계에서 코드를 변경하면 상위 단계 메서드 선언부를 전부 고쳐야 하는 경우가 생길 수도 있다 (p.133)
  • 예외에 의미를 제공하라 (p.135)
  • 특수 사례 패턴 -> 클래스를 만들거나 객체를 조작해 특수 사례를 처리하는 방식 -> 클래스가 예외적인 상황을 캡슐화해서 처리하므로, 클라이언트 코드가 예외적인 상황을 처리할 필요가 없어진다 (p.137)
  • null을 반환하지 마라 -> 메서드에서 null을 반환하고픈 유혹이 든다면 그 대신 예외를 던지거나 특수 사례 객체를 반환하는 것이 좋다. (p.137)
  • null을 전달하지 마라 -> 정상적인 인수로 null을 기대하는 API가 아니라면 메서드로 null을 전달하는 코드는 최대한 피한다 -> 대다수 프로그래밍 언어는 호출자가 실수로 넘기는 null을 적절히 처리하는 방법이 없다. 그러니까 애초에 null을 전달하지 말도록 하자 (p.140)
  • 오류 처리를 프로그램 논리와 분리하면 독립적인 추론이 가능해지며 코드 유지보수성도 크게 높아진다 (p.142)

 

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

여태까지 오류를 처리할만한 코드를 작성해본 적이 없었던 것 같은데, 타이밍 좋게 잘 읽은 것 같다.

다음에 프로젝트를 하게 된다면 오늘 읽은 내용을 생각하면서 오류를 잘 분리하여 처리해봐야겠다.

728x90
반응형

'책 리뷰 > 클린코드' 카테고리의 다른 글

10장 클래스  (0) 2022.03.08
9장 단위 테스트  (0) 2022.03.06
6장 객체와 자료구조  (0) 2022.03.01
5장 형식 맞추기  (0) 2022.03.01
4장 주석  (0) 2022.02.27
728x90
반응형

TIL (Today I Learned)

2022.03.01

오늘 읽은 범위

6장 객체와 자료구조

책에서 기억하고 싶은 내용을 써보세요.

  • 변수 사이에 함수라는 계층을 넣는다고 구현이 감춰지지는 않는다. 구현을 감추려면 추상화가 필요하다 (p.119)
  • 추상 인터페이스를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있어야 진정한 의미의 클래스다 (p.119)
  • 디미터 법칙 -> 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다 (p.123)
  • 잡종 구조 -> 절반은 객체, 절반은 자료 구조인 구조 -> 함수나 타입을 보호할지 공개할지 확신하지 못해서 나오는 어중간한 설계인데, 되도록 피하도록 하자
  • 새로운 자료 타입을 추가하는 유연성이 필요하면 객체, 새로운 동작을 추가하는 유연성이 필요하면 자료구조와 절차적인 코드가 더 적합하다 (p.128)

 

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

최근에 자바 공부를 시작했었는데 이렇게 객체 지향 관련 글은 보니 복습이 된 것 같다. 하지만 다시 봐도 꽤 어렵게

느껴진다. 실제로 프로젝트를 해서 뭔가를 좀 만들어봐야 감을 잡을 수 있을 것 같다. 

제일 기억에 남는 말은 우수한 소프트웨어 개발자는 편견 없이 직면한 문제에 최적인 해결책을 선택한다이다.

결국 개발자가 해야 하는 것이 문제 해결인데 그에 딱 맞는 말인 것 같다. 

728x90
반응형

'책 리뷰 > 클린코드' 카테고리의 다른 글

9장 단위 테스트  (0) 2022.03.06
7장 오류 처리  (0) 2022.03.04
5장 형식 맞추기  (0) 2022.03.01
4장 주석  (0) 2022.02.27
3장 함수  (0) 2022.02.22

+ Recent posts