inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

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

무한 스크롤 쿼리 질문 있습니다.

해결됨

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

학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. select * from article where board_id = 1 order by article_id desc limit 30; 해당 쿼리에서 강사님은 Extra에 null인데 제가 실행하면 using where가 나오네요. using filesort는 안나오는데 크게 상관 없는 부분일까요?

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
eoyeong 댓글 2 좋아요 0 조회수 214

redis 를 compose 로 묶어준 이유가 궁금합니다.

미해결

비전공자도 이해할 수 있는 Redis 입문/실전 (조회 성능 최적화편)

강의 내용 중, redis 를 docker-compose 로 묶어 한번에 띄우도록 설정한 모습을 확인할 수 있었습니다. 이렇게 되면 서버 코드의 변경점이 생겨 수동 재배포를 진행하게 될 때, docker-compose 파일로 실행하게 될 것 같습니다. redis 도 일종의 db라고 생각이 되는데, 서버의 코드가 업데이트 되면 redis 를 다시 docker로 띄운다는 가정이 생기는 것 같은데, 맞는 접근법인지 궁금합니다. 초기 ec2 설정 단계에서 단순히 redis 를 설치해서 사용하면 되지 않나 라고 생각이 됩니다. 만약 캐시 전략의 변경이나, 캐시 데이터의 정합성? 문제가 우려된다면 key를 모두 날려주는 cli 를 실행시키는 방법이 더 유욜할 것 같은데, 강의 편의와 docker-compose 의 유용성을 설명하기 위한 강의 챕터인가요?

  • redis
  • nosql
  • query-tuning
  • performance-tuning
BeakGwa 댓글 2 좋아요 0 조회수 178

C언어 기출문제의 변형 23:00문제 질문할게요

해결됨

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

*ptr++의 경우에는 arr의 값도 증가 시키고 포인터 위치도 변경시키는거고, ++*ptr 일경우에는 바라보고 있는 포인터위치는 변하지 않고 arr의 값만 증가 시키고 끝나는건가요? 제가 지금 이해하고 있는건 *ptr 의 앞에 "++"이 붙으면 값만 선증가시키고, "++"이 뒤에 붙이면 값을 후증가시키고 메모리값도 증가시킨다. 인데 이게 맞나요?

  • python
  • java
  • c
  • 정보처리기사
김영선 댓글 2 좋아요 0 조회수 166

@Value 추가 시 에러 발생

해결됨

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

학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 좋아요 수 구현 부분 강의를 듣고 따라하던 도중 문제가 생겼습니다. ArticleLikeCount의 엔티티에서 version에 @Version을 붙이고 난 후, 테이블의 값을 모두 삭제하고 나서 테스트를 돌리면 에러가 발생합니다. 계속해서.. Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): 위 에러가 계속 발생하네요. 테스트는 like 메서드를 실행했습니다. 이상하게도 강사님 코드로는 정상 작동이 되어서, 그대로 복사해서 붙여넣기로 가져와서 돌려보면 안되네요. 테이블에 데이터가 이미 존재하면 그때부터는 정상적으로 되는 것 같은데, 테이블이 비어있으면 에러가 발생합니다 ㅜㅜ 혹시라도 확인하실 수 있도록 제 프로젝트 파일을 압축해서 올려놓은 링크 공유하겠습니다. ㅜㅜ https://drive.google.com/file/d/1H9UR9UXZhgmBH-XrXoXPc2-dgrixF7b-/view?usp=drive_link

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
박상훈 댓글 4 좋아요 0 조회수 404

Logging 질문

해결됨

실리콘밸리 엔지니어가 가르치는 파이썬 장고 웹프로그래밍

LOGGING ={ 'version':1, 'disable_existing_loggers':False, 'handlers':{ 'file':{ 'level':'DEBUG', 'class':'logging.FileHandler', 'filename':os.path.join(BASE_DIR, 'logs/django.log'), 'formatter':'json', }, 'console':{ 'class':'logging.StreamHandler', 'formatter':'json', }, }, 'formatters':{ 'json':{ 'class': 'pythonjsonlogger.jsonlogger.JsonFormatter', 'format': '%(asctime)s %(levelname)s %(name)s %(message)s', }, }, 'root':{ 'handlers':['file','console'], 'level':'DEBUG', }, 'loggers':{ 'django':{ 'handlers':['file','console'], 'level': 'DEBUG', 'propagate':False, }, }, runserver 하는 순간 {"asctime": "2025-02-14 20:41:50,823", "levelname": "DEBUG", "name": "django.utils.autoreload", "message": "File C:\\Users\\moon\\miniforge3\\envs\\workout\\Lib\\site-packages\\PIL\\__init__.py first seen with mtime 1739352505.781736"} 이런 변경한 적 없는 것들이 자동리로드 되면서 콘솔에 계속 올라옵니다. 이유가 궁금합니다.

  • python
  • django
  • bootstrap
  • rest-api
  • drf
ansghltjd9 댓글 1 좋아요 0 조회수 173

프론트에서 페이지네이션 count 계산법 질문드립니다!

해결됨

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

페이지 번호 공식은 다음 버튼 활성화 유무만 판단하는 거고 이전 버튼 유무는 프론트에서'만' 제어하는 걸까요? 프론트에서도 페이지 번호 공식을 알고 있는걸까요? 2:50초 11~20번 페이지에 있을때 프론트에서 계산한값(601) == 백엔드에서 내려준 값(601) => 같으므로 '다음' 버튼 활성화 프론트에서 계산한값(601) == 백엔드에서 내려준 값(500) => 601 미만 이므로 '다음' 버튼 비활성화 (강의 넘 재밌어요. 게임 하는거 보다 재밌다..)

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
soap 댓글 2 좋아요 0 조회수 222

자세한 설명 부탁드려요 ㅜ

미해결

공공데이터로 파이썬 데이터 분석 시작하기

강사님 안녕하세요 우선 너무 잘 듣고 있고 좋은 강의 정말 감사합니다 . 그런데 수업 내용이 자꾸 현재 버전과 달라서 너무 헷갈려요.. 설명하시는 단축키나, 어디에 들어가 어떻게 입력해야하는지 방법에 대한 설명 없이 내용뿐인 것들이 있어 따라가기 어려운듯해요 ㅜ profiling 한글폰트설정 부록 강의 올려주신 부분에서 터미널 들어가서 경로를 입력하라고 하시는데 어떤 형식으로 어디부터 어디까지 써서 입력해야하는지 모르겠어요.. ~/opt/anaconda3/lib/python3.12/site-packages/pandas_profiling 이렇게 따라 입력하면 저는 아무 반응도 안일어나는데 어떻게 해야할까요?

  • python
  • pandas
  • numpy
ynny 댓글 2 좋아요 0 조회수 222

ui 파일을 py파일로 변환

미해결

[신규 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 강의에서는 너무 짧게 지나가서, 해결을 못하고 있습니다. 컴알못이라,, 자세히 설명 부탁드립니다 ㅠ,.ㅠ... 프로젝트 폴더를 06.GUI폴더로 설정 =>어디서 어떻게 클릭해서 설정하는지 모르겠습니다. 터미널에서 해당 명령어를 실행 "pyside6-uic ui -o py"=>1번부터가 막혀서 실행을 못하고 있습니다.

  • python
  • 웹-크롤링
김형곤 댓글 2 좋아요 0 조회수 199

대규모 트래픽 환경에서는 Jpa 보단 서브쿼리를 활용하시나요?

해결됨

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

22:40에 서브 쿼리를 제시해주셨는데요. 쿼리를 분리하여 애플리케이션 로직으로 풀수 없을때만 nativeQuery를 사용해서 서브쿼리를 즉시 적용하시는 걸까요? 아니면 서브쿼리를 적극적으로 사용하시는 걸까요? 대규모 트래픽 환경에서는 Jpa, Querydsl를 단순한 기능에 사용할때도 조심해서 써야할 것 같아요.. 팀 컨벤션이 도메인을 풍부하게 활용하는 거라면 nativeQuery는 지양해야 할것 같기두 하네요. 지식이 부족해서 가정만 하게 되네요 ㅠ.ㅠ 답변 부탁드립니다~ (반복 학습 필수네요. 강의 1분 1초를 씹고 뜯고 맛보고 즐기면서 공부하겠습니닷!)

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
soap 댓글 2 좋아요 0 조회수 319

boj 3020

해결됨

세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)

안녕하세요 ! 수강전 문제를 풀어보았는데 풀었던 방법이 attributeError 런타임에러가 나왔습니다. 하기 방법에 매몰이 되어서 강의에 집중이 안되어서 이렇게 질문하게 되었습니다 ㅠㅠ 이렇게 풀면 메모리나 시간초과가 날까요? 그리고 어디가 틀려서 런타임에러가 나는지 알수있을까요? import sys # sys.stdin = open('./input.txt', 'r') input = sys.stdin.readlines().strip() from collections import defaultdict W, H = map(int, input().split()) lit = [int(input()) for _ in range(W)] # print(lit) # dict_ = defaultdict() ans = defaultdict() points = [] for y, v in enumerate(lit): if y % 2 == 0: for x in range(H-v, H): points.append((x, y)) else: for x in range(v): points.append((x, y)) for x, z in points: if x in ans.keys(): ans[x] += 1 else: ans[x] = 1 # print(ans) low_cnt = sorted(ans.values())[0] cnt = 0 for k, a in ans.items(): if a == low_cnt: cnt += 1 print(f'{low_cnt} {cnt}')

  • python
  • 코딩-테스트
  • 알고리즘
tocc22 댓글 1 좋아요 0 조회수 139

유저목록 확인 문제 질문드립니다.

미해결

파이썬/장고로 웹채팅 서비스 만들기 (Feat. Channels) - 기본편

def room_users(request, room_name): # room_name으로 해당 방을 찾기 room = get_object_or_404(Room, name=room_name) # 사용자가 방에 참여한 상태인지 확인 if not room.is_joined_user(request.user): return HttpResponse("Unauthorized user", status=401) # 방에 접속 중인 사용자 목록 가져오기 username_list = room.get_online_usernames() return JsonResponse({ "username_list": username_list, }) 저는 하나의 채팅방만 사용하기때문에 room_pk가 아니라 room_name을 전달했습니다. 근데 page not found가 뜹니다. 제가 생각기로는 name = room_name 전달이 제대로 안되어서 이렇게 뜨는거같습니다. room_pk에 관한 부분을 제대로 처리하지 못해 접속하거나 나갈때 뜨는 메세지도 제대로 작동하지 않고 있습니다. class Room(OnlineUserMixin, models.Model): owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="owned_room_set", ) name = models.CharField(max_length=100) class Meta: ordering = ["-pk"] @property def chat_group_name(self): return self.make_chat_group_name(room=self) chat/routing.py from django.urls import path, re_path from chat import consumers websocket_urlpatterns = [ path("ws/chat/<str:room_name>/chat/", consumers.ChatConsumer.as_asgi()), ] chat/urls.py from django.urls import path from app.urls import urlpatterns from chat import views # 향후 url reverse에 활용 app_name = "chat" urlpatterns=[ path("", views.index, name = "index"), path("<str:room_name>/chat/", views.room_chat, name = "room_chat" ), path("<str:room_name>/users/", views.room_users, name = "room_users" ), ] consumers.py from asgiref.sync import async_to_sync from channels.generic.websocket import JsonWebsocketConsumer from chat.models import Room # 모든 유저가 고정된 채널 레이어 그룹을 가질것. class ChatConsumer(JsonWebsocketConsumer): SQUARE_GROUP_NAME = "1" group_name = [SQUARE_GROUP_NAME] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def connect(self): user = self.scope['user'] self.group_name = self.SQUARE_GROUP_NAME if not user.is_authenticated: self.close() else: is_new_join = self.group_name if is_new_join: async_to_sync(self.channel_layer.group_send)( self.group_name, { "type": "chat.user.join", "username": user.username, } ) async_to_sync(self.channel_layer.group_add)( self.group_name, self.channel_name ) self.accept() def disconnect(self, code): if self.group_name: async_to_sync(self.channel_layer.group_discard)( self.group_name, self.channel_name ) user = self.scope['user'] # if self.room is not None: # is_last_leave = self.room.user_leave(self.channel_name, user) # if is_last_leave: # async_to_sync(self.channel_layer.group_send)( # self.group_name, # { # "type": "chat.user.leave", # "username": user.username, # } # ) def chat_user_join(self, message_dict): self.send_json({ "type": "chat.user.join", "username": message_dict["username"], }) def chat_user_leave(self, message_dict): self.send_json({ "type": "chat.user.leave", "username": message_dict["username"], }) def chat_message(self, message_dict): self.send_json({ "type": "chat.message", "message": message_dict["message"], "sender": message_dict["sender"], }) def receive_json(self, content, **kwargs): user = self.scope["user"] _type = content["type"] if _type == "chat.message": message = content["message"] sender = user.username async_to_sync(self.channel_layer.group_send)( self.SQUARE_GROUP_NAME, { "type": "chat.message", "message": message, "sender": sender, } ) else: print(f"Invalid message type : ${_type}") 질문 받아주셔서 감사합니다. 선생님의 파이썬 장고 가이드를 다 보고 이 강의 질문하는게 맞다고 생각합니다. , 제 팀프로젝트 데드라인이 임박하여 파이썬 장고 가이드를 다 보지 못하고, 제대로 공부하지 못하고 채널스를 공부하게 되어 이런 질문을 드리게되는거같아 죄송합니다. 프로젝트가 끝나도 장고 놓지 않고 제대로 이해할수있게 공부하겠습니다. 감사합니다ㅠ

  • python
  • django
  • django-channels
sunnnwo 댓글 2 좋아요 0 조회수 202

XxxResponse를 service 패키지에 두신 이유가 궁금합니다.

해결됨

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

XxxRequest / XxxResponse 클래스를 controller 패키지 하위가 아닌 Service 패키지 하위에 두신 이유가 궁금합니다. 의존성 방향을 Controller부터 단방향을 유지하기 위해 하신것으로 유추 하는 바입니다. 하지만 XxxRequest / XxxResponse가 service 패키지 클래스에 있는게 조금 어색해 보여서요. 저는 controller 하위 패키지에 requeset / response를 두고 facade 혹은 service에 클래스로 묶어서 넘길경우 에는는 domain 계층에 만든 dto를 생성해서 넘깁니다. 제가 생각한게 맞는지 답변 부탁드립니다~ (강의 최고입니다. 저만 듣고 싶어요 흙흙)

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
soap 댓글 1 좋아요 0 조회수 198

카프카를 도입하고 난 뒤 로그로 보여지는 장점을 발견하지 못하고 있습니다.

미해결

실습으로 배우는 선착순 이벤트 시스템

안녕하세요 강사님. 강의 마지막에 API서브모듈에서 직접 MySQL로 여러 쓰레드가 JPA save를 통해 INSERT하는 과부하가 발생하던 것을 카프카를 통해서 처리량을 조절할 수 있다고 말씀하셨습니다. 카프카를 사용하는 것만으로도 처리량이 조절된다는 뜻이 잘 이해가 가지 않습니다. 특히 컨슈머서브모듈에서 보여지는 로그를 확인해보면 여전히 단 건으로 SQL들이 전송되는 것을 확인할 수 있었는데요. 배치방식으로 여러 SQL을 한데 모아 한번에 SQL횟수를 줄여주는 것을 기대했으나 그렇지 않아 어떤 원리로 처리량이 줄어드는 것인지 이해를 못했습니다ㅠㅠ

  • java
  • docker
  • spring-boot
  • kafka
  • redis
창신동 장첸 댓글 2 좋아요 0 조회수 192

webpubsub연결 오류

해결됨

Azure Native로 나만의 GPT 만들기

강의 잘 듣고있습니다. 이번 강의에서 front와 API를 연결하는 작업 도중, 계속 마지막에 토큰까지는 잘 받아오지만 웹소켓을 못 만드는 문제가 발생했습니다. 문제가 무엇일까 계속 고민해보다가 이 강의 가장 처음에 강사님이 진행했던 =을 붙이는 작업이 떠올라 그 =을 다시 지워줬습니다. 그런데 해결이 됐습니다. 제 키에는 =가 마지막에 없더라구요... =가 있는 경우와 없는 경우가 존재하나봅니다. =의 차이가 혹시 무엇인지 알 수 있을까요? 그냥 암호의 일부분일까요?

  • javascript
  • python
  • mongodb
  • azure
  • FastAPI
안현준 댓글 2 좋아요 0 조회수 183

캐시 구현에서 Redis - MongoDB 스코프

미해결

배달앱은 어떻게 내 주변의 맛집을 찾을까?

제가 이해한 구조는 아래와 같습니다. Request -> API -> Service -> Entity Redis에서 캐시 조회 실패하면 redis에서 몽고 db collection 관련 함수를 직접 조회 하는 게 아니라 서비스로 돌아가서 서비스단에서 몽고 db collection 관련 함수를 호출하는게 맞지 않나요? 아니면 주신 코드 처럼 Entity 단에서는 서로를 호출하면서 작동하는게 맞나요?

  • python
  • mongodb
  • FastAPI
파사 댓글 2 좋아요 0 조회수 173

키생성 방식에 따른 성능

미해결

실습으로 배우는 선착순 이벤트 시스템

안녕하세요. 문제점 해결하기 강의에서 실습을 잘 진행했습니다. 실험을 하며 결과를 관측하던 중, @NoArgsConstructor(access = AccessLevel.PROTECTED) @RequiredArgsConstructor @Entity public class Coupon { @Id @GeneratedValue private Long id; } 위와 같이 @GeneratedValue를 적용하면 로그패턴도 달라지고 성능이 급격하게 나빠지더라고요 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 로 지정하면 실습이 잘 진행됩니다. 왜 이런차이가 발생하는지 알 수 있을까요? strategy를 선택하지 않으면 AUTO이며 이는 mysql에서 IDENTITY를 선택한 것과 같게 나와야하는데 예상과 달라 질문드려봅니다.

  • java
  • docker
  • spring-boot
  • kafka
  • redis
창신동 장첸 댓글 2 좋아요 0 조회수 195

선생님 질문 있습니다.

미해결

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준)

1) request.META["HTTP_USER_AGENT"] 실습 5번 내내 NameError로 표기 되지 않습니다. 구글링해도 정확히 어떤 이유인지 잘모르겠습니다. 2) 아래 pwsh 느낌표가 왜 나오는지 궁금합니다.

  • react
  • python
  • django
  • web-api
  • htmx
lkh5040 댓글 1 좋아요 0 조회수 98

안녕하세요 선생님,

미해결

파이썬/장고로 웹채팅 서비스 만들기 (Feat. Channels) - 기본편

#consumers.py from asgiref.sync import async_to_sync from channels.generic.websocket import JsonWebsocketConsumer from chat.models import Room # 모든 유저가 고정된 채널 레이어 그룹을 가질것. class ChatConsumer(JsonWebsocketConsumer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) SQUARE_GROUP_NAME = "square" self.group_name = [SQUARE_GROUP_NAME] self.room = None def connect(self): user = self.scope['user'] if not user.is_authenticated: self.close() else: room_name = self.scope['url_route']['kwargs']['room_pk'] try: self.room = Room.objects.get(pk=room_name) except Room.DoesNotExist: #지정 룸 pk에 룸 인스턴스가 없을 경우 웹소켓 연결요청 수락. pass else: self.group_name = self.SQUARE_GROUP_NAME is_new_join = self.room.user_join(self.channel_name, user) if is_new_join: async_to_sync(self.channel_layer.group_send)( self.group_name, { "type": "chat.user.join", "username": user.username, } ) async_to_sync(self.channel_layer.group_add)( self.group_name, self.channel_name ) self.accept() def disconnect(self, code): if self.group_name: async_to_sync(self.channel_layer.group_discard)( self.group_name, self.channel_name ) user = self.scope['user'] if self.room is not None: is_last_leave = self.room.user_leave(self.channel_name, user) if is_last_leave: async_to_sync(self.channel_layer.group_send)( self.group_name, { "type": "chat.user.leave", "username": user.username, } ) def chat_user_join(self, message_dict): self.send_json({ "type": "chat.user.join", "username": message_dict["username"], }) def chat_user_leave(self, message_dict): self.send_json({ "type": "chat.user.leave", "username": message_dict["username"], }) def chat_message(self, message_dict): self.send_json({ "type": "chat.message", "message": message_dict["message"], "sender": message_dict["sender"], }) def receive_json(self, content, **kwargs): user = self.scope["user"] _type = content["type"] if _type == "chat.message": message = content["message"] sender = user.username async_to_sync(self.channel_layer.group_send)( self.SQUARE_GROUP_NAME, { "type": "chat.message", "message": message, "sender": sender, } ) else: print(f"Invalid message type : ${_type}") room_name = self.scope['url_route']['kwargs']['room_pk'] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^ KeyError: 'room_pk' 이런 에러가 나서, urls.py, views.py, index.html도 맞춰줘 봤지만, 잘 해결이 되질 않습니다. 어떤식으로 이 에러를 처리해야할까요. 오늘도 좋은 하루 되시길 바랍니다. 감사합니다.

  • python
  • django
  • django-channels
sunnnwo 댓글 1 좋아요 0 조회수 117

상세페이지로 이동하는 url을 받아서 이동할때, url유형이 달라요

미해결

[신규 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)

상세페이지 href속성을 찾아 기존페이지 url?상세페이지 url을 적용하여 실습을 성공해 오다가 난관에 부딪혔습니다. html속성값을 보니 아래와 같이 되어 있고 url에 붙이거나 해도 페이지가 로드 되지 않아 어려움을 겪고 있습니다. <a href="Javascript:view_content('869');">처리 일정 문의 드립니다.</a> 위와같은 href가 나타날때는 어떻게 상세페이지로 이동해야 하는지 궁금하고 이럴때 혹시 우회할 수 있는 대안이 있다면 알고 싶어요

  • python
  • 웹-크롤링
민소리 댓글 1 좋아요 0 조회수 123

%0이 짝수라는뜻인가요?

미해결

문과생도, 비전공자도, 누구나 배울 수 있는 파이썬(Python)!

50%2를 하면 25인데 25일경우에는 0이 아닌데 이해가 잘 안되어서요 그냥 %2=0이면 짝수라는 통용되는 개념인가요?

  • python
escho94 댓글 1 좋아요 0 조회수 156

인기 태그

인프런 TOP Writers

주간 인기글