import java.util.Set;
import java.util.HashSet;
class Solution {
public int[] solution(int[] numbers) {
Set<Integer> set = new HashSet<>();// 중복 없이
int len = numbers.length;
for(int i = 0; i < len-1; i ++) {
for(int j = i+1; j < len; j++) {
set.add(numbers[i] + numbers[j]); // 두 개 조합
}
}
// 오름차순 정렬
int[] answer = set.stream()
.mapToInt(Integer::intValue)
.sorted()
.toArray();
return answer;
}
}
Copilot 사용 살펴보기
git 레포지토리 생성 및 브랜치 설정
공통 모듈에 들어갈 의존성 이야기하기
IDE 코드 포매팅 설정
각 서비스의 포트 번호 공유


프론트엔드에서 body에 success 필드로 boolean 값을 주어서 굳이 header를 파악하지 않고 성공 여부에 따른 분기 처리가 수월할 것이라 생각했지만,
만약 HTTP status 값과 다르게 잘못 success 정보가 전달되거나, 성공 여부가 status와 일치하지 않는다고 여겨져 또 다른 불필요한 의사소통 과정이 발생할 수 있다.
추가:
- 두 결과 값이 논리적으로 일치하지 않는다면, 로직상 문제가 존재하는 것이라 판단.
- 1개로 관리하는 것 보다, 문제 발견 가능성 높음 → 빠른 문제 파악 가능
위와같은 이유를 근거로 공통 응답 형식을 채택했다.
영향이 있는 모듈만 빌드 가능하다.
-> Git Diff (커밋이 발생한 모듈만 감지)
Man vs Ai 님이 2차 프로젝트 기간 동안 내내 심혈을 기울여 수립해나간 (진짜 리스펙) 패키지 구조를 슬쩍(리스펙?)해서 팀 패키지 컨밴션으로 제안했다.

이 패키지 구조는 헥사고날 아키텍처와 DDD를 기반으로 하며, 계층 간 의존성 역전(DIP)을 통해 핵심 비즈니스 로직을 보호하는 형태이다.
다만 튜터님께서는 짧은 개발기간동안 패키지 정리에 소요될 시간을 걱정하셨다.
튜터님과의 피드백 이전에 다른 팀원분께서 포맷을 정리해주시면서 도메인 모델에 {Aggregate}.java와 {Entity}.java가 동시에 존재하는 문제가 생겼었는데, 덕분에 패키지의 의도가 잘 보이지 않았음을 깨닫고 패키지 구조를 다시 살펴보면서 정리할 수 있는 계기가 되었다. 팀 노션에 이해하기 어려울듯한 부분에 대해서도 설명을 붙였다.

기존 패키지 구성에서 다음을 수정했다.
application/event를 없애고 외부로 나가는 모든 행위는 application/port/out으로 통일
Consumer는 infrastructure 영역에 위치하며, 별도 인터페이스 구현 없이 바로 Application Service를 주입받아 호출하도록 정리
구현체(Impl) 클래스들의 이름을
~Adapter로 바꿔서 아키텍처의 의도를 조금 더 명확히 드러내기
[ Pagely 서비스 패키지 구조 ]
가이드라인 정도로 수용해주시고, 전체 틀을 훼손하지 않는 한에 패키지 수정은 자유롭게 허용
com/pagely/{domain}service/
│
├── domain (1단계: 핵심 비즈니스 로직 및 규칙)
│ ├── model/
│ │ ├── {Entity}.java ← 엔티티 (핵심 모델)
│ │ ├── {Enum}.java ← 상태/타입 정의
│ │ └── {ValueObject}.java ← 값 객체 (ID, 금액, 주소 등)
│ │
│ ├── repository/
│ │ └── {Domain}Repository.java ← 도메인 레포지토리 인터페이스
│ │
│ ├── service/ (도메인 서비스)
│ │ ├── {ExternalProvider}.java ← 외부 도메인 의존 인터페이스 (포트 역할)
│ │ └── {DomainPolicy}.java ← 도메인 정책 및 비즈니스 검증 로직
│ │
│ ├── event/
│ │ └── {DomainEvent}.java ← 도메인 이벤트 정의 (내부 전파용)
│ │
│ ├── exception/
│ │ └── {DomainErrorCode}.java ← 도메인 전용 에러 코드 정의
│ │
│ └── query/ (조회 최적화 분리 : 선택)
│ ├── {SearchSpec}.java ← 조회 조건 (Specification)
│ ├── {Projection}.java ← 조회 결과 전용 DTO
│ └── {QueryRepository}.java ← 조회 전용 레포지토리 인터페이스
│
├── application (2단계: 유스케이스 흐름 제어 및 Port)
│ ├── service/
│ │ ├── {Domain}CommandService.java ← 트랜잭션 + 흐름 제어 (CUD)
│ │ └── {Domain}QueryService.java ← 조회 로직 처리 (QueryRepository 사용)
│ │
│ ├── dto/
│ │ ├── command/
│ │ │ └── {Command}.java ← 생성/수정/삭제 요청 DTO
│ │ ├── query/
│ │ │ └── {SearchQuery}.java ← 상세 조회 조건 DTO
│ │ └── result/
│ │ ├── {Result}.java ← 서비스 계층 단건 반환 객체
│ │ └── {SummaryResult}.java ← 서비스 계층 목록 반환 객체
│ │
│ └── port/ (외부와 소통하는 접점; 필요시 in/out 하위 패키지 자유 구성)
│ ├── {EventProducer}.java ← 이벤트 발행 인터페이스
│ └── {EventConsumer}.java ← 이벤트 수신 인터페이스
│
├── infrastructure (3단계: 외부 기술 및 상세 구현 - impl 계층)
│ ├── persistence/
│ │ ├── {JpaRepository}.java ← Spring Data JPA 인터페이스 (과할 경우 생략 가능)
│ │ ├── {RepositoryAdapter}.java ← 도메인 Repository 구현체 (impl)
│ │ └── {QueryRepositoryAdapter}.java ← QueryDSL 기반 조회 구현체 (impl)
│ │
│ ├── messaging/ (메시지 브로커 구현)
│ │ ├── kafka/
│ │ │ ├── {ProducerAdapter}.java ← 포트(Producer) 구현체
│ │ │ └── {Listener}.java ← 메시지 소비(Consumer 역할)
│ │ └── rabbitMq/
│ │
│ ├── provider/
│ │ └── {ExternalProviderAdapter}.java ← 외부 서비스 연동 실제 구현 fegin/ (impl)
│ │
│ ├── security/
│ │ ├── config/ ← 보안 관련 설정
│ │ └── {AuthorityCheckAdapter}.java ← 권한 검증 실제 구현 (impl)
│ │
│ └── client/ (외부 API 통신)
│ ├── {FeignClient}.java ← FeignClient 인터페이스
│ └── dto/
│ └── {ExternalResponse}.java ← 외부 API 응답 매핑 DTO
│
└── presentation (4단계: 외부 노출 및 사용자 인터페이스)
├── {Domain}Controller.java ← REST API 컨트롤러
├── {SuccessCode}.java ← 성공 응답 공통 코드 정의
│
└── dto/
├── request/
│ ├── {CreateRequest}.java ← 클라이언트 요청 객체
│ └── {SearchRequest}.java ← 클라이언트 조회 필터 객체
│
└── response/
├── {Response}.java ← 단건 응답 API 스펙
└── {SummaryResponse}.java ← 목록 응답 API 스펙