22분에 나오는 코드의 실행 순서에 질문이 있습니다. 자식 클래스 생성자에 this나 super로 생성자가 적혀있지 않은 경우 자바에서 자동으로 super()를 만들어준다고 알고 있는데 맞나요? 그럼 Chi()에서 this(20)으로 Chi(20)이 실행된 다음, 이 생성자에는 따로 this나 super로 생성자가 적혀있지 않기 때문에 super()로 Par() 생성자가 호출된다고 이해하면 될까요? 질문을 정리하자면, 코드의 정확한 실행 순서가 Chi() -> Chi(int y) -> Par()인지, Chi() -> Par() -> Chi(int y)인지 알고 싶습니다.
4분 58초에 for(i=0;i<4;++i){ if(Data[i]>'c'){ break; } 이 문항에서 위에 나온 배열에 B A D E 가 존재하는데요 c 의 아스키코드는 99 로 인지한 상태로 풀고 나머지 배열에있는 값들은 각각 66 , 65 ,68 ,69 이렇게 해서 브레이크가 안걸리고 i가 3까지 나열한 뒤로 끝나는 것으로 인지했었습니다 그런데 영상 강의에선 D의 값에서 break가 걸린다고 들었는데 왜 그런건지 질문드립니다.
딩코님! 강의 너무 잘 듣고 있습니다~! 강의를 따라가며 디비와 트랜잭션 그리고 락에 관해 심화 내용도 듣고 포폴도 하나하나 잘 채워가고 있습니다! 다름이 아니라 딩코님이 내주신 과제 중에 의문이 있어 질문을 드리게 되었습니다. 1. 현재 학습 진도 4주차 수강 후 락과 트랜잭션 최적화를 수행하고 있습니다. 현재 여러가지 작업(일기 작성, 포인트 적립, AI 댓글 작성 예약, 알림 이벤트 발생)에 대해 facade 계층을 만들어 중요한 작업(일기 작성, 포인트 적립)에 대해서는 트랜잭션을 묶어 우선적으로 처리되게 하고 AI 댓글은 TaskScheduler로 특정 시간 후에 비동기적으로 이루어지게 하며 알림은 spring event로 after commit 후 처리하려 합니다. 2. 어려움을 겪는 부분 현재 이벤트 발행 (트랜잭션 커밋 후 실행됨, after-commit)에 대해 의문이 있습니다. 현재 딩코님이 올려주신 코드에는 @Component @RequiredArgsConstructor @Slf4j public class ImprovedEventJoinWithExternalApiUpdateFacade { private static final String TEST_PHONE_NUMBER = "01012341234"; private final EventExternalUpdateService eventJoinService; private final ExternalEventApi externalEventApi; private final ApplicationEventPublisher eventPublisher; public void joinEvent(Long eventId, Long memberId) { // 1. 기존 서비스로 이벤트 참가 처리 EventWithLockParticipant participant = eventJoinService.joinEventWithTransaction(eventId, memberId); // 2. 외부 API 호출 ExternalEventResponse response = externalEventApi.registerParticipant( eventId, memberId, participant.getEvent().getName() ); if (!response.isSuccess()) { throw new RuntimeException("외부 API 호출 실패: " + response.getErrorMessage()); } // 3. 외부 API 응답으로 참가자 정보 업데이트 eventJoinService.updateExternalId(participant, response.getExternalId()); // 4. 이벤트 발행 (트랜잭션 커밋 후 실행됨) eventPublisher.publishEvent(new EventJoinCompletedEvent( eventId, participant.getEvent().getName(), TEST_PHONE_NUMBER )); } } 이렇게 코드 내에 @Transactional이 걸려있지 않습니다. 그런데 이벤트 리스너에는 @Component @RequiredArgsConstructor @Slf4j public class EventJoinEventListener { private final KakaoTalkMessageApi kakaoTalkMessageApi; @Async @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void handleEventJoinCompleted(EventJoinCompletedEvent event) { try { kakaoTalkMessageApi.sendEventJoinMessage( event.getPhoneNumber(), event.getEventName() ); } catch (Exception e) { log.error("알림 발송 실패. eventId={}, eventName={}", event.getEventId(), event.getEventName(), e); } } } 이렇게 transaction이 커밋된 후에 실행되도록 AFTER_COMMIT이 걸려있는데, 이렇게 되면 이벤트 리스너가 제대로 실행이 안되지 않나요? 제대로 이벤트 리스너가 실행이 되려면 joinEvent부터 @Transactional이 걸려있어야 하지 않나요? 3. 시도해보신 내용 따로 간단하게 코드를 작성하여 테스트해보았습니다. @RequiredArgsConstructor @Component public class StudyFacade { private final StudyService studyService; private final ApplicationEventPublisher eventPublisher; // @Transactional : 주석 처리하면 밑에 eventEvent가 실행되지 않음 public void execute() { studyService.saveStudy(); eventPublisher.publishEvent("event published"); } @Async @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void executeEvent(String event) { System.out.println("event = " + event); } } @RequiredArgsConstructor @Service public class StudyService { private final StudyRepository studyRepository; @Transactional public void saveStudy() { studyRepository.save(new Study("test")); } } 실제로 execute 메서드의 @Transactional을 주석처리하면 밑의 이벤트 리스너인 executeEvent가 실행이 되지 않더라구요. 이러면 ImprovedEventJoinWithExternalApiUpdateFacade의 joinEvent부터 트랜잭션을 걸어야 하니까 딩코님이 말씀하신 트랜잭션을 최대한 작게 나누는 트랜잭션 최적화가 어렵지 않나요? 항상 강의 잘 듣고 있습니다! 감사합니다!
33:56 SELECT count(col2) FROM TABLE WHERE col1 in (2,3) or col2 in (3,5); 에서 결과가 4인점은 이해가 됩니다. (count는 Null 포함 x) 다만 오른쪽 아래 테이블이 헷갈리는 데, 만약 count(col2)가 아닌 col2만 출력하면 아래 처럼 나오는걸로 이해하고 있습니다. col2 ---- Null 6 5 3 3 강사님께서는 count에 해당하는 투플만 테이블만 표현하신건가요? 또 집계함수(sum, avg, max,min,count) 모두 Null은 포함하여 계산하지 않는다고 이해하면 될까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 섹션 5의 <프린터 예제3 - 인터럽트 코드 개선 관련> 질문입니다. printer.addJob(input) 관련하여, 어떤 스레드에서 어디서부터 어디까지 책임지고 실행하는지 헷갈려서 정리해봤는데 검토해주시면 감사하겠습니다. === printer.addJob(input) 은 main 스레드(호출 스택)에서 실행된다. 공유하는 Heap 메모리 영역에 Printer 객체 주소가 있다. main 스레드는 Printer 객체의 jobQueue 변수에도 접근이 가능하고 addJob() 메서드를 호출할 수 있다. 따라서, addJob() 메서드에 대한 스택 프레임도 main 스레드(호출 스택)에 쌓여서 처리된다. === JPA 이후 오랜 만에 영한님 강의를 다시 듣기 시작했는데 재밌네요. 늘 감사합니다.
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 2:33초의 강의 내용 중 비효율이 있을 뿐 로직은 모두 정상 작동한다. 이 부분 말씀이 그냥 소비자가 소비자를 깨우는 상황에도 예를 들어 put(), take() 안의 로직이 작동한다는 거죠? 만약 생성자나 소비자가 같이 대기 하고 있을 때 같은 종류의 스레드만 계속해서 깨울 시에 starvation이 발생할 수 있는 것과는 이야기와는 별개인거 맞을까요?
안녕하세요, 토비님. 현재 MemberRegister 인터페이스는 register 뿐만 아니라 활성화/비활성화, 정보 업데이트 등의 오퍼레이션을 제공하고 있는데요, 해당 인터페이스에 작성된 주석은 회원의 등록과 관련된 기능을 제공한다 여서 ' register 를 제외한 오퍼레이션은 다른 인터페이스에 위치해야 하지 않나?' 하는 생각이 듭니다. 혹은 회원 등록 외 오퍼레이션이 해당 인터페이스에 존재하는게 의도하신 바지만, 주석 내용이 수정되지 않은 걸까요? 궁금한 점을 요약해서 정리하자면, xxxFinder 는 조회와 관련된 오퍼레이션을, xxxRegister 는 생성/수정/삭제와 관련된 오퍼레이션을 가지는 걸까요? 완강 후 회사에서 강의로 알려주신 것들을 이것저것 적용해보며 재밌게 일하고 있습니다, 정말 감사드립니다.