inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

WebApiExRateProvider 템플릿 콜백 패턴을 적용하면서 테스트 코드를 만들어보았습니다.

미해결

토비의 스프링 6 - 이해와 원리

안녕하세요. 우선 한푼도 아깝지 않은 명강의를 만들어주심에 진심으로 감사드립니다. WebApiExRateProvider를 템플릿 콜백 패턴을 적용한 구조로 변경하면서, 토비님께서는 실제 API를 호출하고 콘솔에 찍힌 결과를 보며 진행한 테스트 방식에 의문이 들어 한번 테스트 코드를 만들어보았는데요. 피드백을 받아보고 싶습니다. 코드는 GitHub Repository에 Commit 내역에서 확인하실 수 있습니다. ( Commit 내역 링크 ) 의도에 대해 간단히 설명드리면 반드시 지정된 URL로 API 호출을 보내야 한다는 동작 과 특정 스펙의 JSON을 파싱해서 환율 정보를 반환하는 동작 을 테스트했습니다. 이때 ApiExecutor 의 경우 단순히 API를 호출하고 그 응답을 반환하는 역할이므로 테스트 할 가치가 없다고 판단하여 배제 했습니다. 주로 궁금한 것은 다음과 같습니다. 테스트하려는 기능에 대해 부족하거나 과함은 없는지? Mock을 활용한 테스트 방식에 대해서는 아쉬움이 없는지? 아무래도 Mock을 활용한 테스트에는 찝찝함이 남아있는데, 어떻게 해소할 수 있을지? 토비님이라면 어떤 식으로 테스트를 진행하셨을 지? 다시 한번 좋은 강의 제공해주셔서 진심으로 감사합니다.

  • java
  • spring
생마차라거 댓글 2 좋아요 0 조회수 90

[강의 오류 제보] Navbar 컴포넌트 코드 오류 발견

해결됨

React & FastAPI로 만드는 투표 커뮤니티 플랫폼: 결제 시스템으로 수익화까지!

안녕하세요, '리액트 + FastAPI로 투표 커뮤니티 플랫폼' 강의를 수강 중인 학습자입니다. 강의 자료의 코드를 그대로 따라했을 때 에러가 발생하여 제보드립니다. --- 📍 발생 위치: - 강의 섹션: [섹션 3/ch2. 메뉴바 제작] - 파일: src/Components/Navbar/index.jsx ❌ 발생한 에러: ReferenceError: logout is not defined 🔍 문제 원인: 강의 자료 코드에서 함수는 onLogoutClick , onLoginClick , onSignupClick 으로 정의했으나, 자식 컴포넌트에 전달할 때는 정의되지 않은 logout 변수를 사용하고 있습니다. 현재 강의 자료 코드: ``` javascript const onLogoutClick = () => { ... }; <AuthButtons logout={logout} /> // ❌ logout 미정의 <MobileMenu logout={logout} /> // ❌ logout 미정의 ``` 수정방법: <AuthButtons isAuthenticated={isAuthenticated} isOpen={isOpen} setIsOpen={setIsOpen} onLogoutClick={onLogoutClick} // ✅ 수정 onLoginClick={onLoginClick} // ✅ 추가 onSignupClick={onSignupClick} // ✅ 추가 /> <MobileMenu isOpen={isOpen} setIsOpen={setIsOpen} isAuthenticated={isAuthenticated} onLogoutClick={onLogoutClick} // ✅ 수정 onLoginClick={onLoginClick} // ✅ 추가 onSignupClick={onSignupClick} // ✅ 추가 /> 💡 제안: 이전 강의 자료에서는 올바르게 onLogoutClick 등을 전달하고 있었는데, 특정 시점부터 logout 으로 변경되면서 함수명과 불일치가 발생한 것으로 보입니다. 강의 자료 업데이트 부탁드립니다. 감사합니다.

  • react
  • mysql
  • docker
  • rest-api
  • FastAPI
고리오영감 댓글 2 좋아요 0 조회수 109

13분쯤 테스트하다가 안 된다면?

해결됨

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

저도 13분쯤에 create 테스트를 하다가 안 되어서 삽질했는데, 드디어 됐습니다. 원인은 createdAt, updatedAt에 값을 설정하지 않고 넣으려다 보니, null로 들어가서 에러가 발생했던 것이었습니다. 그리고 mysql에 접속했을 때는 use article; 로 DB에 접근해야 합니다. 저는 use database; 로 접근하고 있었네요. 이 과정에서 GPT의 도움을 많이 받았습니다. 13분쯤 진행다가 나오던 그 500 에러 로그는 애플리케이션을 확인해 봐야 하고요. 테스트 코드의 create 메서드에는 IDE의 설명도 같이 참고했습니다. 왜 오류가 떴는지 알려주더군요.

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
Bruce Han 댓글 2 좋아요 0 조회수 92

bfs 풀이

미해결

자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비

제 자력으로는 bfs로 풀어봤는데 정답이 뜨긴 했습니다. 그리고 선생님이 푸신 기법으로도 제출해보았더니 실행시간은 비슷하더라구요. 이 문제에서만은 bfs로 해결해도 되지만 뒤에 있는 문제를 풀기 전에 알아야할 코드이기에 선수학습 코드로 알고 있으면 될까요? 최소 스패닝 트리 문제는 bfs만으로는 풀 수가 없는걸까요...? 한 집합에서 노드들이 응축이 되지 않고 계속 연결만 되고 있는 상태에서 마지막으로 입력된(연결된) fb가 이 집합의 배열의 값이 되는건가요? 입력 예시로 보면 (1,2), (2,3), (3,4), (1,5)는 결국 하나의 집합인거잖아요? 여기서 5(fb)가 이 집합의 배열값으로 무조건 고정이 되는건지 궁금합니다.

  • java
  • 코딩-테스트
rlgus4531 댓글 1 좋아요 0 조회수 76

writer retry 관련해서 궁금한 점이 있습니다.

미해결

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

반말은 조금 부끄러워서.. 존댓말로 질문드리겠습니다. ItemWriter에서 예외 발생 시 재시도 - 청크 단위로 재시도 관리 1. ItemWriter에서 예외 발생 시 ItemProcessor부터 처리가 재개된다. 2. ItemProcessor에서와 달리, ItemWriter에서의 재시도 횟수는 청크 단위로 관리된다. 요 부분에서 실제로 배치를 돌려보니 writer부터 재시작하는 것을 확인 가능했습니다.. 관련해서 원인을 분석해보니, 아래 결론에 도달했는데 맞을까요? processorNonTransactional() 설정이 켜져있으면 Item 단위로 처리 결과를 캐시에 저장하기때문에 processor는 모두 완료 처리 -> writer부터 시작 processorNonTransactional() 설정이 꺼져있으면 청크 단위로 완료 처리하기때문에 processor부터 다시 시작

  • java
  • spring
  • spring-boot
  • spring-batch
  • backend
박정선 댓글 2 좋아요 1 조회수 82

인프런강의를 듣고 있는데 궁금한게 있어요!!!

해결됨

(2026 최신!) 일주일만에 합격하는 정보처리기사 실기

인프런 강의를 듣는 1인입니다! 인프런 강의 듣고 있는데 공부를 어떤식으로 해야하는지 혹시 책은 따로 없나요 손코딩으로 많이 해보라는데 아직도 감을 못잡고있어요ㅠㅠㅠㅠㅠ 어떻게 해야하죠?.....

  • python
  • java
  • c
  • 정보처리기사
다혜 댓글 2 좋아요 0 조회수 82

getPostData 함수 질문

미해결

손에 익는 Next.js - 블로그 만들기

return 문에 왜 matterResult.data를 반환해주나요? id 와 content만 있으면 되는거 아닌가요?? 추가해주는 이유가 궁금합니다.

  • react
  • 블로그
  • next.js
gmldnjs0402 댓글 1 좋아요 0 조회수 78

버퍼문제?

미해결

김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] package scanner.ex; import java.util.Scanner; public class ScannerWhileEx1 { public static void main(String[] args) { Scanner input = new Scanner( System.in ); while (true) { System.out.print("이름을 입력하세요 (종료를 입력하면 종료): "); String name = input.nextLine(); if (name.equals("종료")) { System.out.println("프로그램을 종료합니다."); break; } System.out.print("나이를 입력하세요: "); int age = input.nextInt(); input.nextInt(); System.out.println("입력한 이름: " + name + ", 나이: " + age); } } } 해당코드를 실행했는데 (줄바꿈처리도 잘 했습니다.) 커서가 저 상태에서 깜빡거리고, 아무 출력도 없어요.

  • java
  • 객체지향
댓글 1 좋아요 0 조회수 73

청크 지향 처리 시 벌크 read 방법?

해결됨

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

킬구형, 청크 지향 처리 시 벌크 read를 할 수 있는 방법이 있어? ItemReader 사용 시 소스에서 1건 씩 데이터를 읽어온다면, 단건 SELECT문이 매번 날아가거나 아니면 JDBC의 ResultSet next()를 사용하는 것 같은데,, 전자면 DB 부하가 너무 심하고 후자여도 네트워크 IO가 꽤 발생할 것 같은데.. 지금 수백? 수천만? 건 정도의 데이터를 마이그레이션 해야하는 업무를 받았는데, 청크 생성 시 DB 부하나 네트워크 트래픽을 좀 줄이고 싶은데 다건 SELECT를 통해 처리하는 방법이 있을까?

  • java
  • spring
  • spring-boot
  • spring-batch
  • backend
djccnt15 댓글 3 좋아요 2 조회수 141

graphql 백엔드 서버가 포폴용 빼곤 접속이 안됩니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

backend-practice 로 시작하는 포트폴리오용 백엔드 서버만 접속이 가능하고 다른 서버들은 현재 접속할 수 없습니다. 이로인해 현재 포트폴리오용 사이트 실습을 제외하고 기본 강의에서 제시해주시는 코드 테스트가 불가능합니다. 약 일주일정도 살짝 넘게 강의 수강하면서 시도하는데 문제가 지속되는 것으로 봐서 관리가 안되고 있는 것 같은데 확인 부탁드립니다.

  • react
  • node.js
  • seo
  • graphql
  • next.js
김용주 댓글 2 좋아요 0 조회수 113

이벤트 루프 실행 관련

해결됨

프론트엔드 마스터클래스

저는 풀스택 주니어입니다. 특수 목적을 위해 바닐라js에서 ,document.innerHTML이나 element.remove(), element.append() 등으로 html element의 생성과 삭제가 빈번한 로직을 다루고 있습니다. 이 때 종종 브라우저 렌더링의 실행 완료에 대해 명확하게 알지 못해서 찝찝한 채로 브라우저에 렌더링 일을 시키고 있습니다. 그러던 중 이벤트 루프 관련 3개 강의(16,17,18강) 를 듣고 복습차, 17강으로 다시 돌아와서 보는 2분18초 경에 브라우저 랜더링에 대해 궁금한게 생겼습니다. 예를 들면 const mySchedule = async () => { await randeringPipelineTask(); //랜더링파이프라인 await macroTask(); // 매크로태스크(); } 으로 구성된 mySchedule 메서드가 있다고 가정하겠습니다. macroTask()는 renderingPipelineTask()의 브라우저 페인트까지 모두 완료를 확인한 후에 실행될까요? 아니면 JS엔진이라는 것은, 페인트는 브라우저에 렌더링을 해달라고 부탁까지만하고 macroTask()를 실행할까요? ('실행의 시작'과 '실행의 끝'을 나눠서 생각해서 그런지 생각하면 할수록 햇갈립니다.)

  • javascript
  • react
  • 함수형-프로그래밍
  • 객체지향
  • next.js
동군 댓글 2 좋아요 0 조회수 170

마지막 헥사고날아키텍쳐 테스트

미해결

토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1

마지막 강의에서 진행한 헥사고날 아키텍처 테스트에서 저는 아래와 같이 에러가 발생하고 있는데 어떻게 수정을 해야 할까요? 소스 코드는 동일한 것 같은데... 무엇이 차이인지 모르겠어요 13:09:39.840 [Test worker] INFO com.tngtech.archunit.core.PluginLoader -- Detected Java version 17.0.12 Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture considering all dependencies, consisting of layer 'domain' ('com.inflearn.splearn.domain..') layer 'application' ('com.inflearn.splearn.application..') layer 'adapter' ('com.inflearn.splearn.adapter..') where layer 'domain' may only be accessed by layers ['application', 'adapter'] where layer 'application' may only be accessed by layers ['adapter'] where layer 'adapter' may not be accessed by any layer' was violated (1 times): Method <com.inflearn.splearn.SplearnTestConfiguration.passwordEncoder()> calls method <com.inflearn.splearn.domain.member.MemberFixture.createPasswordEncoder()> in (SplearnTestConfiguration.java:19) java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture considering all dependencies, consisting of layer 'domain' ('com.inflearn.splearn.domain..') layer 'application' ('com.inflearn.splearn.application..') layer 'adapter' ('com.inflearn.splearn.adapter..') where layer 'domain' may only be accessed by layers ['application', 'adapter'] where layer 'application' may only be accessed by layers ['adapter'] where layer 'adapter' may not be accessed by any layer' was violated (1 times): Method <com.inflearn.splearn.SplearnTestConfiguration.passwordEncoder()> calls method <com.inflearn.splearn.domain.member.MemberFixture.createPasswordEncoder()> in (SplearnTestConfiguration.java:19) at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94) at com.tngtech.archunit.lang.ArchRule$Assertions.check(ArchRule.java:86) at com.tngtech.archunit.library.Architectures$LayeredArchitecture.check(Architectures.java:347) at com.inflearn.splearn.HexagonalArchitectureTest.hexagonalArchitecture(HexagonalArchitectureTest.java:22) at java.base/java.lang.reflect.Method.invoke(Method.java:569) at com.tngtech.archunit.junit.internal.ReflectionUtils.invoke(ReflectionUtils.java:111) at com.tngtech.archunit.junit.internal.ReflectionUtils.invokeMethod(ReflectionUtils.java:103) at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitMethodDescriptor.execute(ArchUnitTestDescriptor.java:203) at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitMethodDescriptor.execute(ArchUnitTestDescriptor.java:173) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

  • java
  • spring
  • spring-boot
  • jpa
  • 리팩터링
  • ddd
inf025 댓글 2 좋아요 0 조회수 103

for문 피라미드 찍는거 질문

미해결

김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음

저는 그냥 이중포문은 복잡해 보여서 psvm { int row = 5; for(int i = 1 ; i <= row; i++) { sout("*".repeat(i)) } 이렇게 풀었는데 답은 제대로 나오긴 하는데 이중포문은 먼가 조건식이 두개를 복잡해서 처음에 아이디어가 안떠올랐는데 저렇게 풀었는데 이중포문으로 풀어야 나중에 더 복잡한 문제도 구현해 낼수 있나요??

  • java
  • 객체지향
채식판다 댓글 1 좋아요 0 조회수 89

vite 버전질문

미해결

타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게

vite 버전) 강의 선생님은 6 버전이던대 저는 7인데 상관없나요 ??

  • react
  • version
jyl08840 댓글 2 좋아요 0 조회수 62

static 임포트 방식 질문 드립니다

미해결

스프링 핵심 원리 - 고급편

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. static 메서드를 사용할 때 어쩔 때는 클래스 자체를 임포트 하시고 어쩔 때는 static 임포트를 하시는데 혹시 기준을 알 수 있을까요?

  • java
djccnt15 댓글 1 좋아요 0 조회수 65

email과 패스워드 VO 질문이 있습니다.

미해결

토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1

안녕하세요 !! 도메인 모델의 값 객체 도입편에서 궁금한게 있습니다. 패스워드는 passwordEncoder를 의존하여 암호화와 매치 여부를 확인합니다. 이메일 vo는 검증 패턴이 member만 사용하는 것이 아니라 다른 곳에서도 사용할 수 있고 중복된 코드를 줄이기 위해서 변경하셨습니다. password도 이메일 vo처럼 매번 passwordEncoder를 주입받는 게 아니라 password VO를 만들어서 관리할 수 있을거같은데 패스워드는 의존성 주입으로 해결하게 되신 이유가 궁금합니다

  • java
  • spring
  • spring-boot
  • jpa
  • 리팩터링
  • ddd
티벳로보 댓글 2 좋아요 0 조회수 107

쇼핑몰관련 질문드립니다.

미해결

(2025 최신 업데이트)리액트 : 프론트엔드 개발자로 가는 마지막 단계

쇼핑몰 만들기 부분을 보고 있는데요, 상품상세페이지 만드는데서 막히네요. 메인에서 제품을 누르면 로그인화면이 뜨고 로그인을 하면 다시 메인으로 가는거까지는 되었는데요, 거기서 다시 목록을 누르면 콘솔창에 해당하는 id정보가 나와야 하는데 App.jsx 에서 에러가 난다고 하는데 그대로 따라한 파일이라 어디가 틀린건지 잘 모르겠네요 import React, { useEffect } from 'react'; import { useParams } from 'react-router-dom'; const ProductDetail = () => { let {id} = useParams(); const getProductDetail = async () => { let url = `http://localhost:5000/products/${id}`; let response = await fetch(url); let data = await response.json(); console.log(data); }; useEffect(()=>{ getProductDetail(); },[]); return ( <div></div> ) } export default ProductDetail; import './App.css'; import 'bootstrap/dist/css/bootstrap.min.css'; import { useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom'; import ProductAll from './page/ProductAll'; import Login from './page/Login'; import ProductDetail from './page/ProductDetail'; import Navbar from './component/Navbar'; import PrivateRoute from './route/PrivateRoute'; function App() { const [authenticate, setAuthenticate] = useState(false); //true이면 로그인이 됨, false이면 로그인이 안됨 useEffect(()=>{ console.log('aaa',authenticate); },[authenticate]); //값이 바뀔때마다 return ( <div> <Navbar/> <Routes> <Route path="/" element={<ProductAll/>}/> <Route path="/login" element={<Login setAuthenticate={setAuthenticate}/>}/> <Route path="/product/:id" element={<PrivateRoute authenticate={authenticate}/>}/> </Routes> </div> ) } export default App; <Route path="/product/:id" element={<PrivateRoute authenticate={authenticate}/>}/> 이부분이 에러가 뜨는거 같아요

  • react
  • redux
  • web-api
댓글 2 좋아요 1 조회수 104

그랩님,[꼭] 답변 부탁드립니다.

해결됨

비전공자를 위한 진짜 입문 올인원 개발 부트캠프

*먼저 이 질문의 글을 그랩님께서 보신다면, [꼭][[꼭] 그랩님, 답변 부탁드립니다], Failed to load resource: the server responded with a status of 404 (Not Found) 상품 상세 페이지 질문입니다. https://inf.run/FB4N9 링크부터 본 뒤 답변을 그 게시물에 해 주신 후 이 질문 글 아래에도 답변 을 부탁 드립니다. 그랩님, 좋은 강의 잘 듣고 있습니다. 다름이 아니라, 아래 질문글에서 단 하나도 수정한 것 없이 몇일 뒤 재부팅만 해주었는데요, VS CODE에서 실행을 해주면 아래와 같이 에러도 줄어들어들었습니다. 그리고 위 그림에서 축구공을 누르면 '상품 상세 페이지'가 아무리 기다려도 뜨지 않고 오른쪽에 에러 가 발생 합니다. 에러 발생 스샷 아래 첨부 합니다. ( 참고로 이전에는 상품 상세 페이지의 상품 정보를 받고 있습니다...가 에러 없이 내용을 잘 불러왔었습니다 . 그런데 왜 지금은 아무리 기다려도 내용을 불러오지 못하는 이유를 모르겠습니다. ) 오른쪽에 에러를 해결하여 상품 정보를 받고 있습니다... 내용이 불러오게 하려면 어떻게 해야 하나요 ? ------------------------------------------------------------------------------------------------- 또한 79강 강의 2분 56초 부터 3분 32초 보면, POSTMAN 테스트 를 하는 부분이 나오는데, 여기서 아래 사진을 보면[왼쪽 메뉴 get product] Body 부분에서 그랩 강사님 화면과 다르게 뜨는데, 이것은 왜 그런 건가요? 어떻게 해야 http://localhost:8080/products/1 , http://localhost:8080/products/2 , http://localhost:8080/products/3 을 제대로 작동하게 할 수 있나요? 마지막으로 [참고 사진]으로 POSTMAN의 잘 작동하는 [get products]사진 첨부해 봅니다. 어떻게 해야 이 모든 에러 를 해결 할 수 있을지에 대해 자세한 답변 부탁 드립니다.

  • HTML/CSS
  • javascript
  • react
  • node.js
  • react-native
  • 머신러닝
  • express
  • tensorflow
isbcom1004 댓글 1 좋아요 0 조회수 94

redis 샘플 공격 데이터 2번 오류

미해결

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

오타 발견 root@4ea86c29f1f7:/data# redis-cli set attack:2 "{\"id\":2,\"timestamp\":\"${TODAY}T09:28:47\",\"targetIp\":\"203.0.113.50\",\"attackType\":\"XSS\",\"payload\":\"<script>alert('HACKED!');</script>\"}" 위 명령어 실행 시, 아래와 같은 에러 메시지 발생! bash: !': event not found 에러 발생 원인 bash: !': event not found 에러는 Bash의 히스토리 확장(history expansion) 때문에 납니다. ! 문자(예: HACKED! )가 들어가면 bash가 ! 로 시작하는 히스토리 토큰(예: !! , !$ , !123 )으로 해석하려 하고, 매칭되는 히스토리 항목이 없으면 event not found 오류가 납니다. set +H # 히스토리 확장 끄기 ... redis-cli set attack:2 "{\"id\":2,\"timestamp\":\"${TODAY}T09:28:47\",\"targetIp\":\"203.0.113.50\",\"attackType\":\"XSS\",\"payload\":\"<script>alert('HACKED!');</script>\"}" ... set -H # # 히스토리 확장 켜기 OK redis key들을 set 하기 전에 히스토리 확장을 끄고 실행할 경우 정상 동작

  • java
  • spring
  • spring-boot
  • spring-batch
  • backend
kiljw316 댓글 2 좋아요 1 조회수 73

언제부터 영상을 볼수 있나요?

해결됨

[Live 챌린지] 6주 완성! 개발 실무를 위한 고농축 바이브코딩 (Cursor AI, Figma)

언제부터 영상을 볼수 있나요? 공지를 해주세요

  • react
  • next.js
  • cursor
  • 프롬프트엔지니어링
  • 바이브코딩
사랑2 댓글 2 좋아요 0 조회수 98

인기 태그

인프런 TOP Writers

주간 인기글