묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결
블랜더- 어플라이 후 미러 모디파이 적용하니 원하는 모양이 안나와요 ㅜ 도와주세요~
apply>all transform , scale(스케일 조정했어서)를 한 뒤 미러 모디파이를 적용하니 아래와 같은 모양이 되었어요어플라이 적용하지 않은 상태에서 바로 미러 적용하면 원했던 모양이 나옵니다강의 들으며 따라하고 있는데 강사분과 동일하게 진행하고있는데 다르게 나와서 막힌 상태입니다.혹시 아시는 분들 있으면 한번만 도와주세용어플라이 후 미러 적용한 모습어플라이 없이 바로 미러만 적용한 모습
-
해결됨MongoDB를 활용하여, 200억건 이상의 데이터 파이프라인 작성법
안녕하세요 혹시 강의하실때 진행하시는 몽고디비 버전은 몇인가요?
!
-
미해결
리액트 강의 추천 받습니다
백엔드 관련 공부하면서 취업 준비하다가 프론트도 준비해야할것 같아서리액트 관련강의를 들을려고 합니다. 기본적인 html, css ,javaScript 지식은 있지만 응용이 부족하여추가적으로 강의 나 공부를 해야하는 수준입니다. 이 상황에서 들을만한 리액트 로드맵이나 강의 추천해 주시면 감사드립니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
npx tailwindcss init 가 안되네요.
강의대로 npx tailwindcss init 을 하게되면 'tailwind'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는배치 파일이 아닙니다. 라고 뜨네요. 어떻게 해결 방법이 없을까요?vscode 재시작해봐도 똑같네요.구글링 해보니, 환경변수에 nodejs 경로를 path에 추가하라고 하는데, 이미 추가되어있구요.아, node버전이 기존에 18버전이 설치되어 있어서 그건 새로 설치하지는 않았습니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
동시성 테스트와 데이터 초기화
안녕하세요 선생님 배운 테스트 강의를 통해 사이드 프로젝트를 하며 성장 중입니다.동시성 테스트를 하던 중 문제가 발생 하였고 해결은 하였으나 다른 방법이 있는지 조언을 구하고자질문을 남기게 되었습니다. 먼저 엔티티에 대한 설명을 드리겠습니다.모임과 모임 참여 테이블이 1 : N모임 참여 회원 테이블이 N : 1 입니다.모임은 최대 인원인 capacity를 가지고 있습니다.여러 회원이 모임에 동시 참여 했을때 인원수를 제한 되는지 보기 위한 테스트 입니다.동시성 문제를 막기 위해 비관적락을 모임을 조회 할때 사용 하였습니다. DB는 MYSQL을 사용 하였습니다.트랜잭션의 격리 수준은 기본인 REPEATABLE READ 을 사용 하였습니다.테스트 트랜잭션에서 모임을 저장 하고 비동기 작업의 다른 스레드에서 모임 조회를 시도 할 경우테스트의 모임 저장은 커밋되지 않은 트랜잭션으로 조회가 불가능한 문제가 있었습니다.문제 해결 방안으로는테스트 트랜잭션 어노테이션 제거비동기 작업 스레드를 통한 트랜잭션 커밋으로 이후 트랜잭션이 모임을 조회 하는 방법테스트의 일관성을 위해 2번 방법을 선택 하였습니다.모임과 회원을 저장하는 부분을 비동기 작업 스레드를 통해 커밋 하고이후 스레드의 트랜잭션으로 조회 하여 데이터를 읽을수 있도록 하였습니다. 테스트는 정상적으로 통과 되었지만 문제가 발생 했습니다.스레드 작업의 트랜잭션 커밋으로 다른 테스트에 영향이 가는 문제 입니다. 원인은 테스트 트랜잭션이 전파 되지 않음에 따라 스레드 작업이 롤백 되지 않았습니다.@Test void not_executors_Tx() { log.info("외부 트랜잭션 시작"); TransactionStatus outer = txManager.getTransaction (new DefaultTransactionAttribute()); log.info("outer.isNewTransaction={}", outer.isNewTransaction()); log.info("내부 트랜잭션 시작"); TransactionStatus inner = txManager.getTransaction (new DefaultTransactionAttribute()); log.info("inner.isNewTransaction={}", inner.isNewTransaction()); } 결과 : outer.isNewTransaction = true / inner.isNewTransaction = true @Test void executors_Tx() { //given log.info("외부 트랜 잭션 시작"); ExecutorService executorService = Executors.newFixedThreadPool(5); TransactionStatus outer = txManager.getTransaction (new DefaultTransactionAttribute()); log.info("outer.isNewTransaction() = {}", outer.isNewTransaction()); log.info("내부 트랜 잭션 시작"); executorService.submit(() -> { TransactionStatus inner = txManager.getTransaction (new DefaultTransactionAttribute()); log.info("inner.isNewTransaction() = {}", inner.isNewTransaction()); }); executorService.shutdown(); } 결과 : outer.isNewTransaction = true / inner.isNewTransaction = false 커밋한 스레드의 결과로 인해 전체 테스트에 영향이 가게 되었습니다.밑의 페이징 정보 조회 테스트를 실행 하기 전에 모임 전체 조회를 해보니 테스터 라는스레드 작업에서 저장한 모임이 조회 되었습니다. 어떻게 하면 커밋된 데이터들이 다른 테스트에 영향을 주지 않을까?를 고민 하였고생각한 해결 방안은 @AfterEach를 사용 하자 였습니다.하지만 해결 되지 않았습니다. 다른 테스트 에선 여전히 커밋된 테스터 모임이 발견 되었습니다.이 부분은 왜 delete가 되지 않았는지 모르겠습니다.추측 하기로는 REPEATABLE READ 격리 수준에서 자신이 트랜잭션을 시작 하였을때 데이터만조회 하고 삭제 할수 있기 때문에 테스트 트랜잭션 에서는 스레드가 추가한데이터를 조회, 삭제가 불가능 해서 발생한 문제 이지 않을까 하는 추측 입니다. 그레서 모든 테스트에 @BeforeEach를 사용 하여 테스트 시작전에데이터를 모두 지우고 테스트 하니 통과 하였습니다. 선생님께 드리고 싶은 질문은 이렇게 해결 한것이 최선인지 궁금합니다.멀티 스레드는 테스트 할때 어떻게 동작 할지 모르기 때문에트랜잭션 어노테이션을 제거 하는 방법이 더 나을까요? @AfterEach void cleanUp() { userEventRepository.deleteAllInBatch(); bookmarkRepository.deleteAllInBatch(); eventRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); } @DisplayName("페이징 정보를 받아 모임을 조회 합니다.") @Test void getPagingEvents() { //given for (int i = 0; i < 10; i++) { Event event = createEvent("테스터" + i, "자전거 모임"); eventRepository.save(event); } Pageable pageable = PageRequest.of(1, 3); //when Slice<EventPreviewResponseDto> slice = eventService.getPagingEvents(pageable); //then assertThat(slice.getContent()) .extracting("author") .containsExactlyInAnyOrder("테스터3", "테스터4", "테스터5"); } @DisplayName("5명의 회원이 동시에 최대 인원이 3명인 모임에 참가 할때 3명만 참여 할 수 있다.") @Test void joinEventWhenParticipateAtTheSameTimeWithConcurrency() throws Exception { //given int taskCount = 5; ExecutorService executorService = Executors.newFixedThreadPool(5); CountDownLatch countDownLatch = new CountDownLatch(taskCount); Event findEvent = executorService.submit(() -> eventRepository.save(createEvent("테스터", "테스트 모임", 3))).get(); List<User> users = executorService.submit(() -> Stream .generate(() -> { User user = createUser("테스터", "testEmail"); userRepository.save(user); return user; }) .limit(taskCount) .toList()).get(); //when AtomicInteger exceptionCount = new AtomicInteger(0); for (User user : users) { executorService.submit(() -> { try { eventService.joinEvent(findEvent.getId(), user.getId()); eventRepository.flush(); // 엔티티 상태를 DB에 강제로 반영 } catch (BusinessException ex) { exceptionCount.incrementAndGet(); } finally { countDownLatch.countDown(); // 카운트다운 } }); } countDownLatch.await(); Long participateCount = executorService.submit( () -> userEventRepository.countParticipantByEventId(findEvent.getId())).get(); executorService.shutdown(); //then assertThat(participateCount).isEqualTo(3); assertThat(exceptionCount.get()).isEqualTo(2); }
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
searchMovies에서 hasNextPage가 필요한 이유
안녕하세요 로펀님. 강의 잘 듣고 있습니다. useInfiniteQuery에서 반환하는 hasNextPage를 이용해 fetchNextPage를 하는데 searchMovies에서 작성한 const hasNextPage = count > page * pageSize 는 사용하지 않는 것 같아서 질문 올립니다! {data?.pages ?.map((page) => page.data) ?.flat() ?.map((movie) => ( <MovieCard key={movie.id} movie={movie} />))}에서도 searchMovies 에서 반환하는 page, pageSize, hasNextPage를 제외하고 data만 쓰시길래 작성하신 이유가 궁금합니다. useInfiniteQuery에서 반환하는 hasNextPage와는 다른 건가요??
-
미해결해외 빅테크 코딩 인터뷰: LeetCode 포기자의 합격 공부법
이해하기 어려운 문제 시간 투자
어려운 알고리즘 문제의 경우 이해가 안되는 경우가 있는데요!이런 경우에 다시 2-3번으로 돌아가 내가 뭘 이해못했는지 고민하는 부분에서 시간투자를 어느정도 하셨나요~? 때로는 문제 난이도가 높아서 정말 잘 이해가 안될때도 있을 것 같은데, 이런 경우에 시간투자를 몇시간까지만 하고 그래도 이해가 안되면 강의에서 언급한 것 처럼 psudo code 자체 흐름을 외워버리고 넘어가셨을까요?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
문제와 풀이2번 궁금증
영한님 안녕하세요. 문제와 풀이 2번을 풀고 고민하고 강의를 학습해도 약간의 의문점이 생겨서 질문드립니다. Thread t1 = new Thread(new MyTask(), "t1"); Thread t2 = new Thread(new MyTask(), "t2"); Thread t3 = new Thread(new MyTask(), "t3"); t1.start(); t2.start(); t3.start(); // 1초 t1.join(); t2.join(); t3.join(); // 대기현재 위와 같은 코드에서 main 쓰레드가 t1, t2, t3에게 작업을 시킵니다. 그리고 t1의 join을 만나니까 t1이 작업이 완전히 끝날때까지 대기상태에 빠집니다. 그리고 t1이 작업이 완료되면 t2.join()이 실행된다면 결과가 아래와 같이 나와야 하는데 왜 이렇게 안 되는지 의문입니다. ㅠㅠt1: 1t1: 2t1: 3t2: 1t2: 2t2: 3...
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
캐릭터가 갑자기 안 움직입니다ㅜ
#include "InputMappingContext.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" void ACharacterPlayer::BeginPlay() { Super::BeginPlay(); APlayerController* PlayerController = CastChecked<APlayerController>(GetController()); if (PlayerController) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->AddMappingContext(DefaultMappingContext, 0); } } } // Called to bind functionality to input void ACharacterPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ALCharacterPlayer::Move); EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::Look); EnhancedInputComponent->BindAction(AttackAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::Attack); } void ACharacterPlayer::Move(const FInputActionValue& Value) { FVector2D MovementVector = Value.Get<FVector2D>(); const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); AddMovementInput(ForwardDirection, MovementVector.X); AddMovementInput(RightDirection, MovementVector.Y); } void ACharacterPlayer::Look(const FInputActionValue& Value) { FVector2D LookVector = Value.Get<FVector2D>(); AddControllerYawInput(LookVector.X); AddControllerPitchInput(LookVector.Y); }코드는 위와 같이 작성을 했습니다. 화요일까지 움직였는데 갑자기 안 움직입니다. 플러그인도 있고, IMC에도 다 설정을 했는데 갑자기 안 움직입니다... 구글에서 찾아봐도 해결이 안됩니다ㅜㅜ...ThirdPersonCharacter 를 추가해서 이 캐릭터를 사용하니 움직입니다. 그래서 ThirdPersonCharacter 의 부모 클래스를 제가 만든 클래스로 설정을 하니 다시 안 움직입니다. 코드 문제인 거 같은데 뭐가 문제인걸까요..
-
미해결
인프런 영상관련 문의
안녕하세요.며칠 전부터 인프런 강의가 소리만 나오고 컨텐츠가 재생이 되지 않는데, 저만 그런걸까요?한 강의만 그런 것이 아니라 모든 강의가 그렇습니다.Mac 사용 중이고, 휴대폰에서 어플로 재생했을 땐 문제가 없습니다.Firefox, Chrome 둘 다 재생이 안되네요..
-
해결됨React, Node.js, MongoDB로 만드는 나만의 회사 웹사이트: 완벽 가이드
npm install --save @tinymce/tinymce-react 오류 입니다.
리액트 버젼이 19.0 이상이라서 안된다고하는데 리액트를 다운그레이드해야하나요??...리액트를 다운그래이드 안하고 사용하는 방법은 없을까요?
-
미해결
[실습 6-4, 5] 정상적인 접근이 아닙니다
action.php<? @session_start(); header("Content-Type: text/html; charset=UTF-8"); include ( './common.php' ); # CSRF Token 검증 로직 $csrf_token_session = $_SESSION["csrf_token"]; $csrf_token_param = $_REQUEST["csrf_token"]; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $csrf_token_session = $_SESSION["csrf_token"]; $csrf_token_param = $_REQUEST["csrf_token"]; // CSRF 토큰 검증 if (empty($csrf_token_session) && empty($csrf_token_param) || $csrf_token_param != $csrf_token_session) { echo "<script>alert('정상적인 접근이 아닙니다.');history.back(-1);</script>"; exit(); } } $mode = $_REQUEST["mode"]; $db_conn = mysql_conn(); if($mode == "write") { $title = xss_html_entity($db_conn->real_escape_string($_POST["title"])); $id = $db_conn->real_escape_string($_SESSION["id"]); $writer = xss_html_entity($db_conn->real_escape_string($_SESSION["name"])); $password = $db_conn->real_escape_string($_POST["password"]); $content = $db_conn->real_escape_string($_POST["content"]); $secret = $_POST["secret"]; $uploadFile = ""; if(empty($title) || empty($password) || empty($content)) { echo "<script>alert('빈칸이 존재합니다.');history.back(-1);</script>"; exit(); } if(!empty($_FILES["userfile"]["name"])) { $uploadFile = $_FILES["userfile"]["name"]; $uploadPath = "{$upload_path}/{$uploadFile}"; if(!(@move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadPath))) { echo("<script>alert('파일 업로드를 실패 하셨습니다.');history.back(-1);</script>"); exit; } } if($secret == "on") { $secret = "y"; } else { $secret = "n"; } $uploadfile = $db_conn->real_escape_string($uploadFile); $content = str_replace("\\r\\n", "<br>", $content); $query = "insert into {$tb_name}(title, id, writer, password, content, file, secret, regdate) values('{$title}', '{$id}', '{$writer}', '{$password}', '{$content}', '{$uploadFile}', '{$secret}', now())"; $db_conn->query($query); } else if($mode == "modify") { $idx = $_POST["idx"]; $title = xss_html_entity($db_conn->real_escape_string($_POST["title"])); $password = $db_conn->real_escape_string($_POST["password"]); $content = xss_html($db_conn->real_escape_string($_POST["content"])); $secret = $_POST["secret"]; $uploadFile = xss_html_entity($_POST["oldfile"]); if(!is_numeric($idx)){ echo "<script>alert('숫자 값만 가능합니당.');history.back(-1);</script>"; exit(); } if(empty($idx) || empty($title) || empty($password) || empty($content)) { echo "<script>alert('빈칸이 존재합니다.');history.back(-1);</script>"; exit(); } # Password Check Logic #$query = "select * from {$tb_name} where idx={$idx} and password='{$password}'"; $query = "select * from {$tb_name} where idx={$idx} and id='{$_SESSION["id"]}'"; $result = $db_conn->query($query); $num = $result->num_rows; if($num == 0) { #echo "<script>alert('패스워드가 일치하지 않습니다.');history.back(-1);</script>"; echo "<script>alert('잘못된 요청입니다.');history.back(-1);</script>"; exit(); } if(!empty($_FILES["userfile"]["name"])) { $uploadFile = $_FILES["userfile"]["name"]; $uploadPath = "{$upload_path}/{$uploadFile}"; if(!(@move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadPath))) { echo("<script>alert('파일 업로드를 실패 하셨습니다.');history.back(-1);</script>"); exit; } } if($secret == "on") { $secret = "y"; } else { $secret = "n"; } $content = str_replace("\\r\\n", "<br>", $content); $uploadFile = $db_conn->real_escape_string($uploadFile); $query = "update {$tb_name} set title='{$title}', content='{$content}', file='{$uploadFile}', secret='{$secret}', regdate=now() where idx={$idx}"; $db_conn->query($query); } else if($mode == "delete") { $idx = $_GET["idx"]; $password = $db_conn->real_escape_string($_POST["password"]); if(!is_numeric($idx)){ echo "<script>alert('숫자 값만 가능합니당.');history.back(-1);</script>"; exit(); } # Password Check Logic #$query = "select * from {$tb_name} where idx={$idx} and password='{$password}'"; $query = "select * from {$tb_name} where idx={$idx} and id='{$_SESSION["id"]}'"; $result = $db_conn->query($query); $num = $result->num_rows; if($num == 0) { #echo "<script>alert('패스워드가 일치하지 않습니다.');history.back(-1);</script>"; echo "<script>alert('잘못된 요청입니다.');history.back(-1);</script>"; exit(); } $query = "delete from {$tb_name} where idx={$idx}"; $db_conn->query($query); } echo "<script>location.href='index.php';</script>"; $db_conn->close(); ?>write.php <div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center"> <h1 class="display-4">Write Page</h1> <hr> </div> <div class="container"> <form action="action.php" method="POST" enctype="multipart/form-data"> <div class="form-group"> <label>Title</label> <input type="text" class="form-control" name="title" placeholder="Title Input"> </div> <div class="form-group"> <label for="exampleInputPassword1">Password</label> <input type="password" class="form-control" name="password" placeholder="Password Input"> </div> <div class="form-group"> <label for="exampleInputPassword1">Contents</label> <textarea class="form-control" name="content" rows="5" placeholder="Contents Input"></textarea> </div> <div class="form-group"> <label for="exampleInputPassword1">File</label> <input type="file" class="form-control" name="userfile"> </div> <div class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input" id="customCheck1" name="secret"> <label class="custom-control-label" for="customCheck1">Secret Post</label> </div> <div class="text-right"> <input type="hidden" name="csrf_token" value="<?=$csrf_token?>"> <input type="hidden" name="mode" value="write"> <button type="submit" class="btn btn-outline-secondary">Write</button> <button type="button" class="btn btn-outline-danger" onclick="history.back(-1);">Back</button> </div> </form> </div> 해커 계정으로 게시물 작성하려고 하는데정상적인 접근이 아니라는 팝업이 뜹니다. 강의대로 코드 작성해도 그렇고 위처럼 수정했을 때도 그렇습니다.
-
해결됨[언리얼 공인 강사 직강] 하루만에 언리얼 엔진5 입문하기
게임 승리해도 시간 지나면 패배하는 문구가 떠요
게임에 승리해도 대기 해서 시간이 지나면 패배했다는 문구가 프린트 되더라고요. 그래서 시간이 끝나면 cast to BP_캐릭터 이거 써서 Is There A coin을 불러 오고 Branch를 통해 false일 경우에 실행시킬려고 해보고 컴파일 해 봤지만 Objet가 지정되어 있지 않다고 에러가 나더라고요.오브젝트를 지정해서 연결할수 있는 노드가 있을까요?
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
vue.js 중급 리포지토리 권한 관련
인프런 아이디: izim0522인프런 이메일:izim0522@naver.com깃헙 아이디: izim5223@gmail.com깃헙 username: junse11입니다!
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
[긴급] 다익스트라 영상강의 문제
영상 강의 중간에 그림을 작성하는 부분으로 넘어갈 때마다 소리는 정상적으로 나오지만 영상이 뚝뚝 끊기는 현상이 발생합니다. 설명에서 가장 중요한 시각 자료를 작성하시는 부분에서 발생하는 현상이라 빠른 수정 부탁드립니다.구간: 1분19초~ 1분 24초, 2분 30초 ~ 3분
-
해결됨QGIS 입문자 올인원 스타터팩 (이론/실습형)
강의 자료 >SECTION_01 어디에서 다운 받을 수 있을가요?
QGIS 레이어 추가/속성 확인(백터;레스터;데이터테이블) 강의 듣고 있는데 자료 다운이 안된어 따라 갈 수 가 없네요, 참고로 , 다운로드에서는 실습 SECTION _4 다운 되었어요. 😀
-
미해결초보자를 위한 git & github 기본기
한번 봐주실 수 있을까요??
강사님이 하시는대로 따라갔는데 저는 왜 이메일이 안뜨는지 궁금합니다!!
-
미해결
React 팀 프로젝트 (로그인 검증 기능)
Supabase의 DB로 로그인 검증 기능을 만들려고 해요 그런데 로그인 검증을 하기 위해서 예외처리를 테스트 하는데 error 400 (Bad request) 가 발생 합니다. 데이터 값이 있으면 로그인은 됩니다. 하지만 존재 하지 않는 값의 예외처리를 할려 하는데 무조건 error 400 (Bad request) 가 나타나내요 이 문제를 해결해 줄 수 있는분 답변 부탁 드립니다. const handleLogin = async (e) => { e.preventDefault(); if (!email || !password) { alert('이메일과 비밀번호를 입력해주세요.'); return; } // 이메일 형식 확인 (정규식 사용) const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailPattern.test(email)) { alert('올바른 이메일 형식을 입력해주세요.'); return; } if (password.length < 6) { alert('비밀번호는 최소 6자 이상이어야 합니다.'); return; } try { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { alert('이메일 또는 비밀번호가 잘못되었습니다.'); return; } if (data?.user) { alert('로그인이 완료되었습니다.'); navigate('/'); } else { alert('회원 정보가 존재하지 않습니다.'); } } catch (err) { console.error('오류 발생:', err); alert('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); } };
-
해결됨카프카 완벽 가이드 - 커넥트(Connect) 편
table.name.format에 관하여..
안녕하세요 선생님. 강의 잘 보고 있습니다.JDBC Sink Connector의 데이터베이스 스키마 설정 문제가 있네요. 찾아보니 JDBC Sink Connector의 내부적인 문제 같습니다... 구글링을 해보니 table.name.format에서 .구분자를 기준으로 데이터베이스 스키마를 지정해주는 것이 저를 포함하여 문제가 있는 사람들도 있던데... 결론은 그냥 되는 config로 사용하자 입니다. 아래의 내용은 혹여나 저와 같은 문제가 생기신다면 참고해 주세요. 공식 포럼과 이슈를 확인해봐도 명확하게 문제의 원인이 무엇인지에 대한 설명은 없습니다. 해결 방안만 있어요.. JDBC Sink Connector 생성하여 Key값을 가지는 Customers 토픽에서 테이블로 데이터 Sink해당 github 링크의 코드를 확인해보시면 connection.url에서 이미 스키마 om_sink를 바라보고 있는데, table.name.format 설정에서 또다시 om_sink 하위에 table을 만드려는 시도에 Exception이 발생합니다. CREATE TABLE om_sink.`om_sink`.`customers_sink_base`라는 SQL 문을 실행하게 되고 이에 exception이 발생합니다. 에러 발생=> om_sink의 om_sink의 customers_sink_base 테이블 생성을 시도함.CREATE TABLE `om_sink`.`om_sink`.`customers_sink_base` -- 이렇게 실행됨. 따라서 connection.url 또는, table.name.format 둘 중 한 군데에는 om_sink를 빼줘야 할 것 같아요. 수정 후 정상 동작
-
미해결Next + React Query로 SNS 서비스 만들기
마이크로 프론트엔드는 레포가 여러개일까요?
안녕하세요! 강의 잘 듣고 있습니다!강의 도중 마이크로 프론트엔드에 대해 여쭤볼게 있어 질문 드립니다!다름이아니라, 3개의 Next 앱을 같은 도메인 아래 뒤에 주소들로만 구분해서 하나로 묶는 마이크로 프론트엔드는 그렇다면 결국 레포지토리가 3개인가요??