묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[초급편] 안드로이드 커뮤니티 앱 만들기(Android Kotlin)
코틀린으로 작업하고
강의를 보면서 코틀린으로 작업하고 나중에 java로 변경해서 해봐도 그대로 되나요?? 아니면 코트 중에 .kt 이렇게 되어있는 부분들을 일일이 다 수정해야하나요???
-
미해결애플 웹사이트 인터랙션 클론!
캔버스 동작 오류
안녕하세요 강의 보면서 따라하던 도중 오류가 생겼는데 어떻게 해결을 해야할지 감이 안와서 질문 남깁니다.. 문제) case3 에서 캔버스가 그려지고 난후 clear가 되지 않아서 계속 겹쳐져서 그려짐 (아래 이미지 첨부) -> clearRect를 사용했더니 fillstyle이 적용안됨 ㅠㅠ 강의를 다시 돌려보면서 혹시 오타라도 났나 싶어 계속 오류를 찾아보고 있는데 발견을 못하겠습니다ㅠㅠ 이 경우에는 어떻게 접근해야 좋을까요? 아래 이미지는 검은색 영역이 그려지고 없어지지 않아서 이미지와 겹쳐있습니다. (이미지는png라서 배경을 따로 줬어요! 배경을 없애도 똑같네요 ㅠ) 근대 캔버스가 움직이는건 아무리 해도 모르겠네요 ㅠㅠ 참고! 가끔 아래서 새로고침후, 위로 올릴때만 정상적으로 동작합니다! 선생님 코드와 다른점 ) 영상을 사진으로 변화한것은 예제와 다른걸 썻는데 , 크기가 제각각이라 제가 임의로 heightRatio를 다르게 썻습니다. 그래서 스크롤을 빠르게 하거나 창크기가 바뀌면 하얀 부분이 나오는데 이거는 제가 다시 계산해서 할 수 있을꺼 같습니다. 그 외 나머지는 css가 조금 다른것 빼고 html, js부분은 똑같습니다. 아래쪽에 제 코드 첨부합니다 (() => { let yOffset = 0; //window.pageYOffset 대신 사용할 변수 let prevScrollHeight = 0; //현재 스크롤위치(yoffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이의 합 let currentScene = 0; //현재활성화된 씬((지금 보고있는 스크린)(=scroll-section) let enterNewScene = false; //새로운 씬이 시작되는 순간 True (씬이 바뀔때 생기는 오류 방지변수) const sceneInfo = [ // 배열 객체는 4개를 만든다(섹션이 4개이기 때문) {//1 type:'sticky', //브라우저 높이의 5배로 scrollHeight 세팅 heightNum:5, // 스크롤높이 scrollHeight:0, objs: { container: document.querySelector('#scroll-section-1'), messageA: document.querySelector('#scroll-section-1 .main-message.a'), messageB: document.querySelector('#scroll-section-1 .main-message.b'), messageC: document.querySelector('#scroll-section-1 .main-message.c'), messageD: document.querySelector('#scroll-section-1 .main-message.d'), canvas: document.querySelector('#video-canvas-0'), context: document.querySelector('#video-canvas-0').getContext('2d'), videoImages: [] }, values: { videoImageCount: 313, imageSequence:[0, 312], canvasOpacity:[1,0,{start:0.9, end:1}], messageA_opacity_in:[0, 1, {start: 0.1, end: 0.2}], messageA_translateY_in:[20, 0, {start: 0.1, end: 0.2}], messageA_opacity_out:[1, 0, {start: 0.25, end: 0.3}], messageA_translateY_out:[0, -20, {start: 0.25, end: 0.3}], messageB_opacity_in:[0, 1, {start: 0.3, end: 0.4}], messageB_translateY_in:[20, 0, {start: 0.3, end: 0.4}], messageB_opacity_out:[1, 0, {start: 0.45, end: 0.5}], messageB_translateY_out:[0, -20, {start: 0.45, end: 0.5}], messageC_opacity_in:[0, 1, {start: 0.5, end: 0.6}], messageC_translateY_in:[20, 0, {start: 0.5, end: 0.6}], messageC_opacity_out:[1, 0, {start: 0.65, end: 0.7}], messageC_translateY_out:[0, -20, {start: 0.65, end: 0.7}], messageD_opacity_in:[0, 1, {start: 0.7, end: 0.8}], messageD_translateY_in:[20, 0, {start: 0.7, end: 0.8}], messageD_opacity_out:[1, 0, {start: 0.85, end: 0.95}], messageD_translateY_out:[0, -20, {start: 0.85, end: 0.95}], } }, {//2 type:'nomal', // heightNum:5 노말에서는 필요없음 scrollHeight:0, objs: { container:document.querySelector('#scroll-section-2') } }, {//3 type:'sticky', heightNum:5, scrollHeight:0, objs: { container: document.querySelector('#scroll-section-3'), messageA: document.querySelector('#scroll-section-3 .a'), messageB: document.querySelector('#scroll-section-3 .b'), messageC: document.querySelector('#scroll-section-3 .c'), pinB: document.querySelector('#scroll-section-3 .b .pin'), pinC: document.querySelector('#scroll-section-3 .c .pin'), canvas: document.querySelector('#video-canvas-2'), context: document.querySelector('#video-canvas-2').getContext('2d'), videoImages: [] }, values: { videoImageCount: 292, imageSequence:[0, 291], canvasOpacity_in:[0,1,{start:0, end:0.1}], canvasOpacity_out:[1,0,{start:0.9, end:1}], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageB_translateY_in: [50, 30, { start: 0.5, end: 0.55 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageB_translateY_out: [30, 0, { start: 0.58, end: 0.63 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageC_translateY_in: [50, 30, { start: 0.72, end: 0.77 }], messageC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageC_translateY_out: [30, 0, { start: 0.85, end: 0.9 }], pinB_scaleY: [0.5, 1, { start: 0.5, end: 0.55 }], pinC_scaleY: [0.5, 1, { start: 0.72, end: 0.77 }], pinB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], pinC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], pinB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], pinC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }] } }, {//4 type:'sticky', heightNum:5, scrollHeight:0, objs: { container:document.querySelector('#scroll-section-4'), canvasCaption: document.querySelector('.canvas-caption'), canvas: document.querySelector('.image-blend-canvas'), context: document.querySelector('.image-blend-canvas').getContext('2d'), imagePath: [ './images/mecolro.PNG', './images/IMG_1667.JPG' ], images: [], }, values: { rect1X: [0, 0, {start:0, end: 0}], rect2X: [0, 0, {start:0, end: 0}], rectStartY: 0, } } ]; function setCanvasImage(){ let imgElem; for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++){ imgElem = new Image(); imgElem.src = `/video/myhome_30frame_4k/frame_${1 + i}.jpg`; sceneInfo[0].objs.videoImages.push(imgElem); }; let imgElem2; for (let i = 0; i < sceneInfo[2].values.videoImageCount; i++){ imgElem2 = new Image(); imgElem2.src = `/video/logo_30frame/frame_${1 + i}.jpg`; sceneInfo[2].objs.videoImages.push(imgElem2); }; let imgElem3; for (let i = 0; i < sceneInfo[3].objs.imagePath.length; i++){ imgElem3 = new Image(); imgElem3.src = sceneInfo[3].objs.imagePath[i]; sceneInfo[3].objs.images.push(imgElem3); }; }; setCanvasImage(); function setLayout(){ //각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++){ if(sceneInfo[i].type == 'sticky'){ sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; } else if(sceneInfo[i].type == 'nomal'){ sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight; } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } yOffset = window.pageYOffset //변수범위가달라서 통일감을 주기위해 똑같은 변수 새로 삽입 let totalscrollHeight = 0; for (let i =0; i < sceneInfo.length; i++){ totalscrollHeight += sceneInfo[i].scrollHeight; if(totalscrollHeight >= yOffset){ currentScene = i; break; } } document.body.setAttribute('id', `show-scene-${currentScene}`); // console.log(sceneInfo); let heightRatio = sceneInfo[currentScene].scrollHeight / 2160 / 3; // if(heightRatio > 0.7){heightRatio = 0.7;}; sceneInfo[0].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; sceneInfo[2].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; // console.log(currentScene); // console.log(heightRatio); }; function calcValues(values, currentYOffset){ let rv; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; //star와 end의 애니메이션 실행 if(values.length == 3){ const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if(currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd){ rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0]; } else if (currentYOffset < partScrollStart){ rv = values[0]; } else if (currentYOffset > partScrollEnd){ rv = values [1]; } } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } return rv; } function playAnimation(){ const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene){ case 0: let sequence = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence],0 ,0); objs.canvas.style.opacity = calcValues(values.canvasOpacity, currentYOffset); if(scrollRatio <= 0.22){ objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else{ objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if(scrollRatio <= 0.42){ objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else{ objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if(scrollRatio <= 0.62){ objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else{ objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if(scrollRatio <= 0.82){ objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else{ objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 1: // 노말타입이라 동작을 안하므로 지워도 되지만 미관상 놔둔다 break; case 2: let sequence2 = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence2],0 ,0); if(scrollRatio <= 0.5){ objs.canvas.style.opacity = calcValues(values.canvasOpacity_in, currentYOffset); } else{ objs.canvas.style.opacity = calcValues(values.canvasOpacity_out, currentYOffset); } if(scrollRatio <= 0.22){ objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else{ objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if(scrollRatio <= 0.57){ objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else{ objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if(scrollRatio <= 0.83){ objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else{ objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } // case3에서 그려질 canvas를 case2에서 미리 동작하게 만들어주자 (코드는 반복, 수치만 살짝 바꿈) if(scrollRatio > 0.9){ // case2에서 사용되는 objs와 values값이 다르지만 if문을 통해 영역을 설정했으므로 const로 다시 선언해준다! const objs = sceneInfo[3].objs; const values = sceneInfo[3].values; const widthRatio = window.innerWidth / objs.canvas.width; const heightRatio = window.innerHeight / objs.canvas.height; let canvasScaleRatio; if(widthRatio <= heightRatio){ canvasScaleRatio = heightRatio; } else {canvasScaleRatio = widthRatio;} objs.canvas.style.transform = `scale(${canvasScaleRatio})`; objs.context.fillStyle = 'white'; objs.context.drawImage(objs.images[0],0 ,0); const canvasCalcWidth = document.body.offsetWidth / canvasScaleRatio; const whiteRectWidth = canvasCalcWidth * 0.2; values.rect1X[0] = (objs.canvas.width - canvasCalcWidth) / 2; values.rect1X[1] = values.rect1X[0] - whiteRectWidth; values.rect2X[0] = values.rect1X[0] + canvasCalcWidth - whiteRectWidth; values.rect2X[1] = values.rect2X[0] + whiteRectWidth; // 시작위치는 초기값으로 설정 (values.rectnX[0]) objs.context.fillRect( parseInt(values.rect1X[0]), 0, parseInt(whiteRectWidth), objs.canvas.height ); objs.context.fillRect( parseInt(values.rect2X[0]), 0, parseInt(whiteRectWidth), objs.canvas.height ); } break; case 3: let step = 0; // 가로세로 모두 꽉차게 하기 위해 여기에 세팅 (계산 필요) const widthRatio = window.innerWidth / objs.canvas.width; const heightRatio = window.innerHeight / objs.canvas.height; let canvasScaleRatio; if(widthRatio <= heightRatio){ canvasScaleRatio = heightRatio; // 캔버스보다 브라우저창이 홀쭉한 경우 } else {canvasScaleRatio = widthRatio;} // 캔버스보더 브라우저창이 납작한 경우 objs.canvas.style.transform = `scale(${canvasScaleRatio})`; objs.context.fillStyle = 'black'; objs.context.drawImage(objs.images[0],0 ,0); // 캔버스 사이즈에 맞춰 가정한 innerwidth와 innerheight const canvasCalcWidth = document.body.offsetWidth / canvasScaleRatio; const canvasCalcHeight = window.innerHeight / canvasScaleRatio; if(!values.rectStartY){ values.rectStartY = objs.canvas.offsetTop + (objs.canvas.height - objs.canvas.height * canvasScaleRatio)/2; values.rect1X[2].start = (window.innerHeight /2) / scrollHeight; values.rect2X[2].start = (window.innerHeight /2) / scrollHeight; values.rect1X[2].end = values.rectStartY / scrollHeight; values.rect2X[2].end = values.rectStartY / scrollHeight; } // 캔버스 폭 넓이 조절 const whiteRectWidth = canvasCalcWidth * 0.2; values.rect1X[0] = (objs.canvas.width - canvasCalcWidth) / 2; values.rect1X[1] = values.rect1X[0] - whiteRectWidth; values.rect2X[0] = values.rect1X[0] + canvasCalcWidth - whiteRectWidth; values.rect2X[1] = values.rect2X[0] + whiteRectWidth; objs.context.fillRect( parseInt(calcValues(values.rect1X, currentYOffset)), 0, parseInt(whiteRectWidth), objs.canvas.height ); objs.context.fillRect( parseInt(calcValues(values.rect2X, currentYOffset)), 0, parseInt(whiteRectWidth), objs.canvas.height ); console.log(parseInt(calcValues(values.rect1X, currentYOffset))); //캔버스가 브라우저 상단에 닿은 경우부터 이미지 블랜드된 후 다시 스크롤되는 것을 3단계 step으로 나눈다 if(scrollRatio < values.rect1X[2].end / 9){ //캔버스가 브라우저 상단에 닿지 않은 단계 step = 1; console.log('before') objs.canvas.classList.remove('sticky'); } else { //이미지가 블랜드되고 스케일이 조정되는 단계까지 step = 2; console.log('after') objs.canvas.classList.add('sticky'); objs.canvas.style.top = `${-(objs.canvas.height - objs.canvas.height * canvasScaleRatio)/2}px`; // if(){ // //스케일 조정되고 다시 스크롤 되는 단계 // step = 3; // }; }; break; } // console.log(currentScene); } function scrollLoop(){ enterNewScene = false; prevScrollHeight = 0; for (let i = 0; i < currentScene; i++){ prevScrollHeight += sceneInfo[i].scrollHeight; } if(yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight){ enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); } if(yOffset < prevScrollHeight){ enterNewScene = true; if(currentScene == 0) return; currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } if(enterNewScene) return; playAnimation(); } window.addEventListener('scroll',() => { yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener('load', () => { setLayout(); sceneInfo[0].objs.context.drawImage(sceneInfo[0].objs.videoImages[0],0 ,0); }); //DOMContentLoaded 도 많이사용 (이미지가 로딩안되도 로딩시키는 매서드) 하지만 여기서는 이미지가 중요하기 때문에 로드를 사용한다 window.addEventListener('resize',setLayout); })();
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
코드 for문을 이용해 포스팅 업로드시 발생하는 에러
안녕하세요 강사님 "장고 기본 CBV API (Generic display views) (2)" 보며 강사님과 같이 포스트를 여러개 만들기 위해서 for문을 이용했는데요~ 위와 같은 에러가 떠서 구글링을 해봤지만 찾지 못했는데 혹시 해결할 수 있는 힌트가 있을까요? 감사합니다..
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 궁금한 점이 있어 질문 드립니다
1. 소켓 송수신 버퍼가 실제로 TCP 단에서 다루는 버퍼가 되는 것인가요? 2. send() 함수가 실패하는 경우는 송신 버퍼가 가득 차는 경우인데 수신 측에서 recv를 하지 않는 경우를 제외하고 어떤 경우에 실패하는지 너무 궁금합니다. 3. 실제로 유저 애플리케이션 계층에서 송신 데이터가 많다고 할 때 TCP가 어느 정도 속도로 송신버퍼를 비우는지(얼마나 빨리 보내주는지) 알기 위해서 어떤 정보를 확인해야 될까요?
-
미해결따라하면 취업되는 게임기획 강의!
시스템 구조도
게임초보라서 시스템 구조도가 잘 와닿지 않는데요 일반 it프로젝트 시스템 아키텍쳐의 클래스 다이어그램과 연결지을 수 있을까요? 어떻게 생각해야 할까요
-
미해결Vue.js 시작하기 - Age of Vue.js
v-model 한글
좋은 강의 감사합니다! 질문이 있어 글 남깁니다. <input v-model="message" type="text" /> <p>{{ message }}</p> 강의대로 위와같이 코드를 짰고, 영어는 input에 치는 즉시 아래에 잘 나옵니다! 다만 한글은 바로 나오지가 않고 엔터를 누르거나 영어를 입력해야 아래에 뜹니다ㅠㅠ 왜 이런 문제가 발생하는지 궁금합니다!!
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
index.html 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. MemberListServlet에서 강의와 동일하게 w.write("<a href=\"/index.html\">메인</a>"); 이렇게 했는데 회원 등록 후 "메인"을 누르면 http://localhost:8080/index.html 이것이 아닌 http://localhost:8080/servlet/members/index.html 여기로 이동하면서 오류 화면이 나옵니다. 코드는 동일하게 했는데 어디서 문제가 발생 한건가요?
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
싱글톤 패턴 구현방법 3 - 다음을 직접 설명해 보세요
안녕하세요 백기선님! 강사님의 수업 잘 듣고 있습니다. 강의를 보며 정리하던 중에 한가지 궁금증이 생겨서 질문드립니다. 강사님의 pdf 파일에 싱글톤 패턴 구현방법 3에 있는 다음을 직접 설명해 보세요 2번에 checked exception을 던진다면이라는 질문이 있는데 제가 알기로는 checked exception은 compile 시점에 나는 예외라고 알고 있습니다. static 변수가 메모리에 올라가는 시점은 class 파일이 메모리에 로딩되는 시점이라고 알고 있는데 이때 메모리에 로딩되는 시점은 run time이 아닌가요? 제가 자바를 공부한지 얼마 안돼 헷갈려서 질문드립니다. 감사합니다!
-
미해결윤재성의 만들면서 배우는 Spring MVC 5
8강 xml셋팅시 오류 질문있습니다.
12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 서버 버전 이름: Apache Tomcat/9.0.55 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: Server 빌드 시각: Nov 10 2021 08:26:45 UTC 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: Server 버전 번호: 9.0.55.0 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 운영체제 이름: Windows 10 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 운영체제 버전: 10.0 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 아키텍처: amd64 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 자바 홈: C:\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_16.0.2.v20210721-1149\jre 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: JVM 버전: 16.0.2+7-67 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: JVM 벤더: Oracle Corporation 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_BASE: C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: CATALINA_HOME: C:\tomcat 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: -Dcatalina.base=C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: -Dcatalina.home=C:\tomcat 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: -Dwtp.deploy=C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: --add-opens=java.base/java.lang=ALL-UNNAMED 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: --add-opens=java.base/java.io=ALL-UNNAMED 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: --add-opens=java.base/java.util=ALL-UNNAMED 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: -Dfile.encoding=UTF-8 12월 01, 2021 1:25:25 오전 org.apache.catalina.startup.VersionLoggerListener log INFO: 명령 행 아규먼트: -XX:+ShowCodeDetailsInExceptionMessages 12월 01, 2021 1:25:25 오전 org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR 버전 [1.7.0]을(를) 사용한, APR 기반 Apache Tomcat Native 라이브러리 [1.2.31]을(를) 로드했습니다. 12월 01, 2021 1:25:25 오전 org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR 용량정보들: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true]. 12월 01, 2021 1:25:25 오전 org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: APR/OpenSSL 설정: useAprConnector [false], useOpenSSL [true] 12월 01, 2021 1:25:25 오전 org.apache.catalina.core.AprLifecycleListener initializeSSL INFO: OpenSSL이 성공적으로 초기화되었습니다: [OpenSSL 1.1.1l 24 Aug 2021] 12월 01, 2021 1:25:25 오전 org.apache.coyote.AbstractProtocol init INFO: 프로토콜 핸들러 ["http-nio-8080"]을(를) 초기화합니다. 12월 01, 2021 1:25:26 오전 org.apache.catalina.startup.Catalina load INFO: [918] 밀리초 내에 서버가 초기화되었습니다. 12월 01, 2021 1:25:26 오전 org.apache.catalina.core.StandardService startInternal INFO: 서비스 [Catalina]을(를) 시작합니다. 12월 01, 2021 1:25:26 오전 org.apache.catalina.core.StandardEngine startInternal INFO: 서버 엔진을 시작합니다: [Apache Tomcat/9.0.55] 12월 01, 2021 1:25:27 오전 org.apache.jasper.servlet.TldScanner scanJars INFO: 적어도 하나의 JAR가 TLD들을 찾기 위해 스캔되었으나 아무 것도 찾지 못했습니다. 스캔했으나 TLD가 없는 JAR들의 전체 목록을 보시려면, 로그 레벨을 디버그 레벨로 설정하십시오. 스캔 과정에서 불필요한 JAR들을 건너뛰면, 시스템 시작 시간과 JSP 컴파일 시간을 단축시킬 수 있습니다. 12월 01, 2021 1:25:27 오전 org.apache.catalina.core.ApplicationContext log INFO: No Spring WebApplicationInitializer types detected on classpath 12월 01, 2021 1:25:27 오전 org.apache.coyote.AbstractProtocol start INFO: 프로토콜 핸들러 ["http-nio-8080"]을(를) 시작합니다. 12월 01, 2021 1:25:28 오전 org.apache.catalina.startup.Catalina start INFO: 서버가 [1997] 밀리초 내에 시작되었습니다. 8강에서 home controller를 만들고 나면 500에러가 뜨고, 콘솔창에 test1이라던지 home이 나와야되는데 500에러가 뜨지 않고, jsp파일을 만들어도 400에러만 뜹니다. 오타가 있나해서 올려주신 소스를 복붙해서 진행했는데도 같아요... 문제가 뭘까요?...ㅠㅠ
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
timeTraceAop만들고 SpringApplication 실행하는데 걸린 시간이 안나오네요..
결과창이 이렇게 뜨는데 아무리 고쳐봐도 안되네요.. *************************** APPLICATION FAILED TO START *************************** Description: The bean 'timeTraceAop', defined in class path resource [com/example/hellospring/Service/SpringConfig.class], could not be registered. A bean with that name has already been defined in file [C:\Users\zzang\Downloads\java\hello-spring\build\classes\java\main\com\example\hellospring\aop\TimeTraceAop.class] and overriding is disabled. Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
Github 권한요청 드립니다
강사님 vue강좌 하나빼고 다 수강중인데 권한요청 부탁드립니다 인프런:calla987@gmail.com github:calla987@gmail.com git:calla987
-
미해결[파이토치] 실전 인공지능으로 이어지는 딥러닝 - 기초부터 논문 구현까지
GAN real/fake데이터 shape 질문입니다
여러 GAN을 살펴보았는데, discriminator에서 real데이터와 fake데이터의 shape은 무조건 같아야하나요? 요즘 GAN들은 그렇게 설계되었는지 하는지 궁금합니다
-
해결됨모든 개발자를 위한 HTTP 웹 기본 지식
컬렉션 - 디렉토리, 스토어 - 저장소에 관한 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요! 영한님 강의 자료 관련해서 질문이 있습니다! 컬렉션의 디렉토리와 스토어의 저장소의 용어와 관련된 질문 PUT 설명에서 스토어의 '클라이언트가 리소스의 URI를 알고 관리'라는 설명과 관련된 질문 이렇게 두가지를 질문드리고자 합니다. 컬렉션의 디렉토리, 스토어의 저장소라는 용어에 관한 질문 컬렉션(Collection) 설명에서 "서버가 관리하는 리소스의 디렉토리" 라는 설명이 나오는데 조금 이해가 되지 않는 부분이 있어서 질문드려요. 디렉토리(directory) 라는 단어의 뜻은 위키피디아를 참고해서 요약해보자면, 파일 시스템 카탈로그 구조 정도로 볼 수 있을 것 같은데요. 컬렉션이 저장되는 저장소는 여러가지가 있겠지만 디렉토리라고 표현하신 이유가 궁금했습니다. 저는 포괄적인 의미로 저장소라고 생각하고 있었거든요! 또, PUT 설명에서는 저장소라고 표현하셔서 왜 컬렉션은 디렉토리고, 스토어는 저장소지? 하는 의문도 들었습니다. PUT 설명에서 스토어의 '클라이언트가 리소스의 URI를 알고 관리'라는 설명과 관련된 질문 여기서 스토어는 "클라이언트가 관리하는 리소스 저장소, 클라이언트가 리소스의 URI를 알고 관리" 라고 되어있는데요, 실질적으로 관리하는 주체는 서버가 아닌가 해서 여쭤봅니다! 답변 미리 감사드립니다.❤️
-
미해결그림으로 배우는 쿠버네티스(v1.30) - {{ x86-64, arm64 }}
vagrant up 명령시 에러 발생
안녕하세요. 오늘부터 조훈님의 강의를 듣게 되었습니다. vagrant up 을 했을 때 아래와 같이 에러가 발생하는데 원인과 해결책을 알 수 있을까요? 감사합니다.
-
해결됨실전! 스프링 데이터 JPA
무제한 스크롤 관련 질문 드립니다.
타임라인 형태 조회 API를 제공 하려다가 중복에 관한 문제에 직면하여 조언을 얻고 자 합니다. 데이터가 로드 된 후. 신규 데이터가 등록 / 삭제 등 프로세스가 일어 난 다음에 다음 페이지를 호출 할 때 생기는 이슈 입니다. pageRequest, slice로 구현 시 신규 데이터가 입력 된 경우 중복으로 데이터가 보이는 케이스가 생기고, 삭제 된 경우 예상치 못하게 데이터가 빠지는 현상이 있습니다. ex) 주어진 데이터 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 size 5 1페이지에 10, 9, 8, 7, 6 이 뿌려 진 상태 조회 된 상태에서 신규 데이터 12, 11 이 추가 됩니다. 이 상태에서 2페이지를 호출 합니다. -> db에서는 12~8까지를 1페이지 7~3까지를 2페이지로 판단하여 7, 6, 5, 4, 3 을 더보기로 뿌려주며 7, 6 번이 중복으로 리스트에 보이게 되고 있습니다. 이 강의는 들은지 4개월이 넘었는데 모바일 더보기 관한 내용을 말씀하셨던 것 같아서 오늘 다시 들어봤지만 Slice의 내용 이었고 제가 직면한 이슈는 아직 해결 되지 않았네요. 조사를 좀 해보니. 오라클의 rownum 같은..? 성격의 데이터로 어디까지 데이터를 불러 왔는지에 대한 값등으로 해결 한다고 찾긴 했는데요. 그 방향으로 native쿼리로 해결을 해볼까 고민하다가 영한님/배민에서는 어떻게 처리 할까 궁금해서 질문을 남깁니다. 제가 못 찾는건지 jpa에서 이러한 이슈 해결해주는 기능을 지원해주는지도 궁금합니다. (없는 것 같네요 ㅠ) 날씨 추운데 건강 챙기세요. 명강의 잘 보고 있습니다.
-
미해결고수가 되는 파이썬 : 동시성과 병렬성 문법 배우기 Feat. 멀티스레딩 vs 멀티프로세싱 (Inflearn Original)
멀티프로세싱 질문
안녕하세요, 강사님. 좋은강의를 좋은기회로 제공해주시는데 제가 너무 많은 질문을 하지 않는가 죄송스럽네요... 강의가 너무 좋아서 복습하다가 헷갈리는 부분들을 다시한번 여쭤봅니다. 1. 멀티프로세스 데이터공유 방법 중 Value, Array는 acquire/release를 안해주면 프로세스가 그 변수에 접근하는 순서는 보장할 수 없는것이 맞는것이죠? (thread에서 배운 Lock 개념처럼) 2. 파이썬 코드에서 parent process가 있고 제가 만든 child process가 있을때, child process가 끝났다면(is_alive()가 False로 더이상 그 프로세스는 뭔가 더 하는일이 없음) 그 child process가 자원을 사용 안한다고 이해해도 되나요? 아니면 그래도 역시 쓸데없는(?) 자원 소비가 있을까요? 만일 있다면, 어떻게 그것을 방지할 수 있을까요? 3. 2번과 유사하게... thread에 대해서도 is_alive()가 False면 그 thread가 쓸데없이 작동하는 경우는 없다고 이해하면 되나요? (잘은 모르지만 multi-thread는 concurrency 개념으로 일정시간별 반복되며 여러 쓰레드가 작동된다 이해하고 있습니다) 만일 아니라면, 그 더이상 하는일 없는 thread는 작동되지 않도록 추가작업을 어떻게 해줘야 하나요?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
lombok @Getter로 수정되지 않도록 하는 가장 좋은 방법이 궁금합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. 실무에서 class 멤버 중 collections가 있을 때 lombok @Getter로 수정되지 않게 하려면 어떤 방법이 가장 좋은지 궁금합니다. 강의 내용 중 실무에서는 lombok @Getter는 사용하는 것이 편리하지만 @Setter는 사용하면 변경 지점이 많아져 관리가 힘드므로 권장하지 않는다고 말씀해주셨습니다. 하지만 관련해서 찾아보니 class 멤버 중 list 같은 collections가 있다면 @Getter로도 데이터 변경이 가능합니다. 실제로 "엔터티 설계시 주의점" 강의에서 연관 관계 메서드에서 아래와 같이 Getter로 데이터를 변경해주셨는데요. (강의 23:55) //==연관 관계 메서드==//public void setMember(Member member) { this.member = member; member.getOrders().add(this);} 이렇게 한다면 Getter가 Setter처럼 쓰일 수 있으므로 역시 변경 지점이 많아질 수 있을 것 같습니다. 따라서 실무에서는 Getter가 Getter로서의 역할만 할 수 있도록 해주실 것 같은데요. 어떤 방법이 제일 좋은지 궁금합니다. 구글링으로 찾아봤을 때는 2021년까지도 이슈가 있고 @Value도 정확한 대안은 아닌 것 같습니다. https://github.com/projectlombok/lombok/issues/1504#issue-268909818 https://github.com/projectlombok/lombok/issues/1504#issuecomment-803578805 감사합니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
(공유) useSWR data가 안 들어가거나 또는 채널이동 안되시는 분들은 봐주세요.
저와 같은 실수를 하실까봐 해결했던 방법 공유하겠습니다. import 부분만 제외한 나머지 다른 부분들은 코드를 똑같이 적었다고 생각했지만 서버에서 false와 data를 받는 건 잘 됐으나, 로그인이 되질 않아 이상하다고 생각하여 data에 대한 log를 찍어봤습니다. 계속 undefined가 나오길래, fetcher 함수에 이상함을 감지하고 쳐다본 결과, // data가 안들어가지는 이유 코드 import axios from 'axios'; const fetcher = (url: string) => axios .get(url, { withCredentials: true, }) .then((res) => {res.data}); export default fetcher; .then((res)=> {res.data}); 이렇게 하면 데이터가 아예 들어가질 않더군요...;; 습관이란게 무섭네요ㅎㅎ 위 코드를 밑에 처럼 바꾸시면 data가 잘 들어가지고 channel로 잘 이동되실겁니다. import axios from 'axios'; const fetcher = (url: string) => axios .get(url, { withCredentials: true, }) .then((res) => res.data); export default fetcher; 혹시 저와 같은 실수를 하시는 분이 계실수도 있으실 것 같아서 시간을 줄여드리고자 공유하도록 하겠습니다.
-
미해결실전! 스프링 데이터 JPA
안녕하세요 다시 들으니 햇갈리네요 Slice
안녕하세요 Slice 는 페이지 번호랑 상관이 없는거같은데 ( 페이지 total을 안져옴) -초반에 말씀해주신 모바일 설명 을 듣고 Silce 는 무한 스크롤 할때 사용하는거같은데... 그런데 페이지 번호 메소드는 가지고 있는게 햇갈립니다 assertThat(page.getNumber()).isEqualTo(0); //페이지 번호 (14:53 참고) =================== 두번째 질문 map() 으로 dto 변환은 람다식 map() 이거랑 일치하는거죠 ??
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
메모리 풀 할당 사이즈 관련
MemoryPool* pool = new MemoryPool(size) 부분에서 할당 메모리 크기인 size가 각 for문 마다 고정되어야 한다고 생각했습니다. 그런데 강의 코드에서는 아래와 같이 size가 for loop를 한번 돌 때 마다 늘어나더라고요. Memory::Memory() { int32 size = 0; int32 tableIndex = 0; for (size = 32; size <= 1024; size += 32) { MemoryPool* pool = new MemoryPool(size); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } for (; size <= 2048; size += 128) { MemoryPool* pool = new MemoryPool(size); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } for (; size <= 4096; size += 256) { MemoryPool* pool = new MemoryPool(size); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } } 제가 강의를 듣고 생각한건 0~1024 byte까지는 32 byte단위, ~2048 byte까지 128 btye단위, ~4096 byte까지 256 byte단위로 할당 한다고 생각했거든요. 근데 위 코드에서 첫번째 for문을 예를 들면 처음에는 Memory Pool을 32 byte 사이즈로 할당하는데 그다음에는 64 byte, 그다음은 96 byte ... 로 할당 사이즈가 점진적으로 증가하더라고요. 저는 1024 byte까지는 32byte로 쭉 하다가, 1024 byte부터 128 byte 단위로 할당할것이라고 생각했습니다. 그래서 저는 아래와 같은 식으로 되어야 하지 않을까 생각했습니다. Memory::Memory() { int32 size = 0; int32 tableIndex = 0; for (size = 32; size <= 1024; size += 32) { MemoryPool* pool = new MemoryPool(32); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } for (; size <= 2048; size += 128) { MemoryPool* pool = new MemoryPool(128); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } for (; size <= 4096; size += 256) { MemoryPool* pool = new MemoryPool(256); _pools.push_back(pool); while (tableIndex <= size) { _poolTable[tableIndex] = pool; tableIndex++; } } } 제가 이해하지 못한 부분이 어떤것인지 알고 싶습니다.