DIP로 컴포넌트 순환 의존을 끊으려면 시그니처의 타입까지 옮겨야 한다
강의를 만들면 빈 커리큘럼도 함께 생기게 하고 싶었다. 강의 생성 서비스에서 커리큘럼 생성 포트를 한 줄 부르자 테스트 두 개가 깨졌다. 하나는 DB의 유니크 제약이고, 하나는 아키텍처 테스트의 순환 금지 규칙이다. 순환은 의존성 역전 원칙(DIP)으로 풀었다. 인터페이스를 쓰는 쪽 패키지로…
강의를 만들면 빈 커리큘럼도 함께 생기게 하고 싶었다. 강의 생성 서비스에서 커리큘럼 생성 포트를 한 줄 부르자 테스트 두 개가 깨졌다. 하나는 DB의 유니크 제약이고, 하나는 아키텍처 테스트의 순환 금지 규칙이다. 순환은 의존성 역전 원칙(DIP)으로 풀었다. 인터페이스를 쓰는 쪽 패키지로…
커리큘럼 편집 서비스의 메서드는 모두 세 줄이다. 커리큘럼을 찾고, 도메인 메서드를 부르고, 저장한다. 로직은 전부 도메인에 있고 도메인 테스트는 꼼꼼하다. 강의는 이 서비스가 너무 단순하다며 테스트를 과제로 남겼다. 나는 그 과제를 하기 전에 서비스를 먼저 커밋했는데, 강의 코드에 있던 버그…
도메인 코드에서 수업을 지우는 방법은 리스트에서 빼는 것이다. JPA의 orphanRemoval은 그렇게 빠진 엔티티를 DB에서도 지워 준다. 편한 설정이지만 커리큘럼에서는 켤 수 없었다. 수업 이동이 “한 리스트에서 빼서 다른 리스트에 넣는” 동작이고, JPA 스펙은 고아가 된 엔티티를 다른 관계에 다시 넣지…
커리큘럼 편집 요청은 전부 숫자로 온다. “섹션 0번의 수업 2번을 섹션 1번의 0번 자리로 옮겨라” 같은 식이다. 리스트 인덱스로 애그리거트 구조 편집을 구현하면 코드는 짧다. 대신 remove가 한 번 일어나면 그 뒤 원소의 인덱스가 하나씩 당겨진다는 사실을 계속 의식해야 한다.…
강의 애그리거트에는 강사, 소개, 공개 상태가 들어 있다. 다음은 실제 학습 내용이다. 강의는 여러 수업으로 이뤄지고, 수업이 많으니 섹션으로 다시 묶는다. 수업과 섹션은 강의에 속한 것처럼 보이니 Course 아래에 매달고 싶어진다. 이 글의 커리큘럼 애그리거트 트리 설계는 그 선택지를 버리는…
2026년 9월 15일 오후, 앱 리포의 dev CI가 Docker VM 안에서 로그를 멈췄다. 시작 4분 뒤였고 빨간불은 안 떴다. 마지막 줄 다음이 그냥 없었고, 41분을 침묵하다 cancelled가 됐다. 오전에 같은 파이프라인이 9분에 두 번 통과한 날이다 앱 CI와 서버 CI가…
같은 파일을 두 번 열고, 그중 하나를 dup()으로 복제하면 파일 디스크립터가 셋이 된다. 셋 다 같은 파일을 가리킨다. 그런데 하나로 5바이트를 읽고 나서 셋으로 한 바이트씩 읽으면 이렇게 나온다 fd 3과 fd 5는 이어서 읽고 fd 4만 처음부터 읽는다. 셋…
메모리가 모자라면 성능이 조금씩 나빠질 것 같다. 실제로는 그렇지 않다. 물리 메모리를 512MiB로 묶어 두고 프로그램이 실제로 쓰는 메모리만 늘려 가며 같은 작업을 세 바퀴씩 돌렸다 작업 집합이 67% 늘었는데 걸린 시간은 1,122배가 됐다. 그 사이에 성능이 완만하게 떨어지는 구간은…
프로그램이 &변수로 얻는 주소는 실제 메모리 칩 위의 자리가 아니다. 아래는 같은 프로세스 안에서 코드·전역 변수·힙·스택의 주소를 뽑고, 각각이 실제로 어느 물리 프레임에 올라가 있는지 커널에 물어본 결과다 왼쪽 가상 주소는 코드에서 힙, 스택으로 질서 있게 늘어서 있다. 오른쪽 물리…
스레드 네 개가 같은 변수를 각각 100만 번씩 1 증가시키면 400만이 나와야 한다. 실제로 돌려 보면 300만이 나오고, 다시 돌리면 220만이 나온다. 같은 코드인데 실행할 때마다 답이 다르다 이 문제를 잠금으로 막는다는 것까지는 알려져 있는데, 잠금이 실제로 어디서 일어나는지는 덜…