묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[아파치 카프카 애플리케이션 프로그래밍] 개념부터 컨슈머, 프로듀서, 커넥트, 스트림즈까지!
컨슈머 랙 모니터링 질문
안녕하세요. 강의 잘 듣고 있습니다! 컨슈머 랙 모니터링 부분 강의를 듣고 있는데 의문이 생겨서 질문 드립니다. 컨슈머 랙을 모니터링하다가 사용량이 많아지게 되면 데이터 처리를 위해 컨슈머 개수와 파티션 개수를 늘려 병렬 처리량을 늘리는 방법이 좋다라고 말씀 하셨는데요. 이전 강의에서는 파티션 수를 늘리면 다시 줄일 수 없기 때문에 처음에 잘 선정해야 한다라고 들어서 이 부분이 약간 헷갈리는 거 같습니다. 많은 데이터량을 처리하려면 파티션 수를 늘리는 방법말고는 없을 거 같은데 설날같이 일시적인 트래픽이 증가하는 날을 위해 평소에도 과도한 파티션 수로 운영하는게 더 좋을까라는 의문도 같이 생기네요. 혹시 현업에서는 어떠한 방식으로 처리하고 있으신가요? 좋은 강의 감사합니다.
-
해결됨이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
8강 Getter Setter 에 대한 질문이 있습니다.
안녕하세요 교수님.CPP에 대한 이해가 아직 많이 부족해서 수업을 듣던 중 질문이 생겼습니다. 조금 이상한 질문일 수도 있을것같은데,FString 멤버 변수의 Getter Setter 멤버 함수는FORCEINLINE FString& GetName() { return Name; }FORCEINLINE void SetName(const FString& InName) { Name = InName; }이렇게 인라인 함수 선언과 참조자 반환으로 성능을 중시한 반면, ECardType 열거형 멤버 변수의 Getter Setter의 경우에는ECardType GetCardType() const { return CardType; }void SetCardType(ECardType InCardType) { CardType = InCardType; }이렇게 선언하여 안정성을 추구한 것처럼 보이는데, 이런 설계 이유나 판단 기준이 무엇인가요? 객체의 크기와 특성에 따라 적절한 설계 방법이 조금씩 다르기 때문일까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
retweet 관련 질문이 있습니다.
다름이 아니라 리트윗빼고는 문제가 없습니다.하지만 리트윗을 하게 되면 데이터베이스에 userid가 null로 들어가면서 게시글을 불러올때 userid가 없기때문에 오류가 나는 것으로 보입니다... 해결해보려고 노력하는 중입니다만 어디가 문제인지 잘 모르겠습니다.const express = require("express"); const multer = require("multer"); const path = require("path"); const fs = require("fs"); const { Post, Image, Comment, User, Hashtag } = require("../models"); const { isLoggedIn } = require("./middlewares"); const router = express.Router(); try { fs.accessSync("uploads"); } catch (error) { console.log("uploads폴더가 없으므로 생성합니다."); fs.mkdirSync("uploads"); } const upload = multer({ storage: multer.diskStorage({ //어디에 저장할지 diskStorage => 하드디스크에 저장 destination(req, file, done) { done(null, "uploads"); }, filename(req, file, done) { // 제로초.png const ext = path.extname(file.originalname); // 확장자 추출(.png) const basename = path.basename(file.originalname, ext); // 제로초 done(null, basename + "_" + new Date().getTime() + ext); // 제로초15184712891.png }, }), limits: { fileSize: 20 * 1024 * 1024 }, // 20MB }); router.post("/", isLoggedIn, upload.none(), async (req, res, next) => { // 보기에는 "/"로 되어있지만 실제로는 "/post"로 되어있다. try { const hashtags = req.body.content.match(/#[^\s#]+/g); //hashtag 정규식 const post = await Post.create({ content: req.body.content, UserId: req.user.id, }); if (hashtags) { const result = await Promise.all( hashtags.map( (tag) => Hashtag.findOrCreate({ //있으면 가져오고 없으면 추가해라 where: { name: tag.slice(1).toLowerCase() }, }) //[[노드, true], [리액트, true]] 이런식으로 나옴 //slice는 글자만 떼기 위해 ex ) #react인 경우 react만 꺼냄 ) ); await post.addHashtags(result.map((v) => v[0])); //위에 같은 형식이기 때문에 0번째만 꺼내야함 } if (req.body.image) { if (Array.isArray(req.body.image)) { //여러개의 이미지를 올린 경우 const images = await Promise.all( req.body.image.map((image) => Image.create({ src: image })) ); await post.addImages(images); } else { const image = await Image.create({ src: req.body.image }); await post.addImages(image); } } const fullPost = await Post.findOne({ where: { id: post.id }, include: [ { model: Image, }, { model: Comment, include: [ { model: User, //댓글 작성자 attributes: ["id", "nickname"], }, ], }, { model: User, //게시글 작성자 attributes: ["id", "nickname"], }, { model: User, //좋아요 누른 사람 as: "Likers", attributes: ["id"], }, ], }); res.status(201).json(fullPost); //다시 프론트로 돌려주기 } catch (error) { console.error(error); next(error); } }); router.post("/:postId/comment", isLoggedIn, async (req, res, next) => { //:postId는 동적으로 바뀐다. //POST /post/comment // 보기에는 "/"로 되어있지만 실제로는 "/post"로 되어있다. try { const post = await Post.findOne({ //이 게시물이 진짜 있는지. where: { id: req.params.postId }, }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다."); } const comment = await Comment.create({ content: req.body.content, PostId: parseInt(req.params.postId, 10), //문자열로 넘어가기 때문에 int형으로 바꿔줘야한다. UserId: req.user.id, }); const fullComment = await Comment.findOne({ where: { id: comment.id }, include: [ { model: User, attributes: ["id", "nickname"], }, ], }); res.status(201).json(fullComment); } catch (error) { console.error(error); next(error); } }); router.patch("/:postId/like", isLoggedIn, async (req, res, next) => { //PATCH /post/1/like\ try { const post = await Post.findOne({ where: { id: req.params.postId } }); if (!post) { return res.status(403).send("게시글이 존재하지 않습니다."); } await post.addLikers(req.user.id); res.json({ PostId: post.id, UserId: req.user.id }); } catch (error) { console.error(error); next(error); } }); router.delete("/:postId/like", isLoggedIn, async (req, res, next) => { //DELETE /post/1/like try { const post = await Post.findOne({ where: { id: req.params.postId } }); if (!post) { return res.status(403).send("게시글이 존재하지 않습니다."); } await post.removeLikers(req.user.id); res.json({ PostId: post.id, UserId: req.user.id }); } catch (error) { console.error(error); next(error); } }); router.delete("/:postId", isLoggedIn, async (req, res, next) => { // DELETE /post/10 try { await Post.destroy({ where: { id: req.params.postId, UserId: req.user.id, }, }); res.status(200).json({ PostId: parseInt(req.params.postId, 10) }); } catch (error) { console.error(error); next(error); } }); router.post( "/images", isLoggedIn, upload.array("image"), //PostForm.js에서input에 올린 이미지가 배열로 들어감 (이미지를 여러장 올릴 수 있게 하기 위해서) async (req, res, next) => { // POST /post/images/ //이곳은 이미지 업로드 후 실행되는 부분, 업로드는 위에 upload에서 이미 다 올라감 console.log(req.files); res.json(req.files.map((v) => v.filename)); //프론트로 보내줌 } ); router.post("/:postId/retweet", isLoggedIn, async (req, res, next) => { // POST /post/1/retweet try { const post = await Post.findOne({ where: { id: req.params.postId }, include: [ { model: Post, as: "Retweet", }, ], }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다."); } if ( req.user.id === post.UserId || (post.Retweet && post.Retweet.UserId === req.user.id) ) { return res.status(403).send("자신의 글은 리트윗할 수 없습니다."); } const retweetTargetId = post.RetweetId || post.id; const exPost = await Post.findOne({ where: { UserId: req.user.id, RetweetId: retweetTargetId, }, }); if (exPost) { return res.status(403).send("이미 리트윗했습니다."); } const retweet = await Post.create({ UserId: req.user.id, RetweetId: retweetTargetId, content: "retweet", }); const retweetWithPrevPost = await Post.findOne({ where: { id: retweet.id }, include: [ { model: Post, as: "Retweet", include: [ { model: User, attributes: ["id", "nickname"], }, { model: Image, }, ], }, { model: User, attributes: ["id", "nickname"], }, { model: Image, }, { model: Comment, include: [ { model: User, attributes: ["id", "nickname"], }, ], }, ], }); res.status(201).json(retweetWithPrevPost); } catch (error) { console.error(error); next(error); } }); module.exports = router; //node에서는 import와 export defau lt를 사용하지 않고 require를 사용한다. //리트윗 case RETWEET_REQUEST: draft.retweetDone = false; draft.retweetLoading = true; draft.retweetError = null; break; case RETWEET_SUCCESS: draft.retweetLoading = false; draft.retweetDone = true; draft.mainPosts.unshift(action.data); break; case RETWEET_FAILURE: draft.retweetLoading = false; draft.retweetError = action.error; break; default: break; } }); export default reducer;//리트윗 function retweetAPI(data) { return axios.post(`/post/${data}/retweet`); //data는 formdata다 } function* retweet(action) { try { const result = yield call(retweetAPI, action.data); yield put({ type: RETWEET_SUCCESS, data: result.data, }); } catch (err) { console.error(err); yield put({ type: RETWEET_FAILURE, error: err.response.data }); } }
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
카이제곱 독립성 검정에서 각 항목의 빈도수가 이상하게 나와요.
import pandas as pd df = pd.DataFrame({ '남자': {'합격': 100, '불합격': 200}, '여자': {'합격': 130, '불합격': 170}}) from scipy.stats import chi2_contingency chi2_contingency(df)Chi2ContingencyResult(statistic=5.929494712103407, pvalue=0.01488951060599475, dof=1, expected_freq=array([[115., 115.], [185., 185.]]))위 코드를 실행하면 expected_freq 값이 행별로 동일하게 나오는데.. 혹시 이유가 있을까요?
-
미해결나도코딩의 자바 기본편 - 풀코스 (20시간)
섹션 12 에러 (코드는 같은데 선생님만 에러 안 뜸)
섹션 12 예외처리 사용자 정의 예외에서 AgeLessThan19Exception가 선생님 화면에는 에러없이 잘 넘어가지만, 실제로는 클래스를 따로 분리하거나 static class AgeLessThan19Exception를 사용해야하는거 아닌가요? 전 에러때문에 코드 실행이 아예 안됩니다.
-
미해결
김영한 스프링 한번에 구매시
안녕하세요김영한 선생님의 스프링 한번에 구매시 블프25%할인이 들어가는데묶음 구매시 추가20%쿠폰은 추가할인은 안되는건가요??추가 할인은 어려운지 확인 부탁드리겠습니다
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
GoRoute List 위치 질문입니다.
List<GoRoute> 를 go_router.dart가 아닌 auth_provider.dart에 넣은 이유가 있을까요?작동은 잘 되지만 코드가 헷갈릴 때가 있어 질문드립니다.라우터 관련 코드들은 go_router에 넣으면 가독성이 더 편해질 것 같은데 auth_provider에 넣은 이유가 있을까요??
-
해결됨Golang을 통한 백엔드 개발 및 환경 구축하기
delete 에러 관련되서 질문이 있습니다.
2023/11/20 20:44:01 http: panic serving [::1]:8034: runtime error: invalid memory address or nil pointer dereferencegoroutine 51 [running]:net/http.(*conn).serve.func1() C:/Program Files/Go/src/net/http/server.go:1854 +0xbfpanic({0xec01a0, 0x126f410}) C:/Program Files/Go/src/runtime/panic.go:890 +0x263github.com/dev-yakuza/study-golang/gin/start/repository.(*UserRepository).Delete(0xc0000a4030, {0x12466f8, 0x1}) C:/go_gin/src/CURS_SERVICE/repository/user.go:42 +0x36agithub.com/dev-yakuza/study-golang/gin/start/service.(*User).Delete(...) C:/go_gin/src/CURS_SERVICE/service/user.go:27github.com/dev-yakuza/study-golang/gin/start/network.(*userRouter).delete(0xc000444530, 0xc000456100) C:/go_gin/src/CURS_SERVICE/network/user.go:104 +0x1cagithub.com/gin-gonic/gin.(*Context).Next(...) C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0005841a0, 0xc000456100) C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620 +0x66bgithub.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0005841a0, {0xfeda80?, 0xc00045e0e0}, 0xc000456200) C:/go_gin/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576 +0x1ddnet/http.serverHandler.ServeHTTP({0xfecb10?}, {0xfeda80, 0xc00045e0e0}, 0xc000456200) C:/Program Files/Go/src/net/http/server.go:2936 +0x316net/http.(*conn).serve(0xc0004fa090, {0xfee018, 0xc0000a27e0}) C:/Program Files/Go/src/net/http/server.go:1995 +0x612created by net/http.(*Server).Serve C:/Program Files/Go/src/net/http/server.go:3089 +0x5ed관련된 에러가 나고 있습니다.for index, user := range u.userMap { if user.Name == userName { u.userMap = append(u.userMap[:index], u.userMap[index+1:]...) isExisted = true continue } } 해당코드에서 user가 nil일 경우에도 for문이 실행이 되고 있습니다. 혹시 이게 u.userMap이 자동적으로 뒤에 nil이 있는 것으로 확인이 됩니다. 혹시 다른 설정하신게 있으실까요?아니면 append가 패치된 상황일까요?일단은for index, user := range u.userMap { if user != nil { if user.Name == userName { u.userMap = append(u.userMap[:index], u.userMap[index+1:]...) isExisted = true continue } } }이렇게 해결 했습니다.
-
미해결스프링 부트 - 핵심 원리와 활용
build.gradle 변경
강의를 듣던 중 프로젝트 설정이 사진처럼 바뀌면서 실행이 되지 않습니다 이 문제는 어떻게 해결할 수 있을까요?
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
DB질문입니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] Mybatis 강의에서 수업을 쭉 따라가다보면-의존성 추가-@Mapper 인터페이스 생성-xml 파일 생성;이후에 바로 테스트를 실행하시는데이 과정에는 H2 DB의 url, id, pw를 넣어주는 설정 작업이 없는것 같은데 dataSource랑 connection은 어떻게 얻어오고 mybatis는 어떻게 db와 연결이 되는건가요???
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
11강 내용중 FStruct 안에 GetTypeHash 함수 friend 선언
friend 키워드는 인자가 클래스일때 private , protected 변수에 접근이 자유롭게 가능하다로 알고있는데요 여기서 들어오는 인자는 FStruct 구조체이므로 모든 변수는 public 이기 떄문에 딱히 의미가 없는부분일까요 ?..
-
해결됨디지털포렌식 입문자를 위한 디지털포렌식 전문가 2급 실기 시험대비 강의(Encase/Autopsy)
질문입니다.
시험장 제공 증거 usb에 이미지 파일이 있는 경우, 별도의 이미지 생성과정 없이 쓰기방지 설정하지 않고 해당 이미지 파일을 이용 autopsy나 ftk 이미저로 바로 분석을 하면되는 것인가요?
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
예시문제 작업형2(신버전) 질문입니다.
학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!질문과 관련된 영상 위치를 알려주면 더 빠르게 답변할 수 있어요먼저 유사한 질문이 있었는지 검색해보세요분명 CSV 파일 예시는pred0010 이렇게 되어있는데,pred[:,1]로 하면 확률로 표시되는데... 그래도 가능할까요?
-
미해결자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)
회문검사 알파벳을 위하여 아스키코드를 활용 해보았습니다.
감사합니다.function solution(args) { let answer = "YES"; const char = args.toLowerCase(); const originalArray = []; for (const val of char) { if (val.charCodeAt() >= 97 && val.charCodeAt() <= 122) { originalArray.push(val); } } if (originalArray.join("") !== originalArray.reverse().join("")) answer = "NO"; return answer; } console.log(solution("found7, time: study; Yduts; emit, 7Dnuof"));
-
해결됨빅데이터 클러스터 구축 패키지; 성공을 향한 로드맵
QJM의 Split Brain 해결법과 Zookeper의 Split Brain 해결법의 차이에 대한 질문
안녕하세요. 강사님의 강의를 듣는 도중, 질문의 내용과 같이, Zookeper의 Split Brain 방식과 QJM의 Split Brain 방식의 차이가 헷갈려서, 질문 드리게 되었습니다.제가 이해한 바는 다음과 같습니다.먼저, Network File System의 문제점은 네트워크 문제 발생시에 동기화 문제가 발생하는 Split Brain Issue가 발생합니다. 이는, 두개의 Active NameNode가 생기기 때문에, 데이터의 corruption이 발생하기 때문에, 저희는 Quorum Journal Manager방식을 채택한 것입니다. 이때, QJM의 경우에도 Split Brain 이슈가 발생이 가능하나, 자체적으로 해결할 수 있다고 했습니다. 해당 방법을 찾아보니, 충분한 수의 Journal Node가 살아있다면, 데이터의 일관성을 유지하기 위해 다수결 원칙을 적용하여 정상적인 Jouranl Node들 간의 동의를 얻게 된다는 점입니다. 저는 해당 방법을 찾아보며, zookeper와 같은 Consoliation Algorithms 방식을 사용하고 있구나... 생각이 들었습니다. 그러니까 Split Brain 이슈 중 하나인 데이터 충돌이 발생했을 때, 맞지 않는 데이터를 지우고, 다수가 가지고 있는 데이터로 통일한다는 것인가..? 라는 생각이 들었습니다. 그러다가, Final Wrap UP 수업에서, zookeper의 경우 NN을 모니터링하며, 장애발생시 (이를 테면, Split Brain과 같은 이슈), StandBy NameNode를 Active NameNode로 전환하며, 여러 개의 Standby NN이 있을 경우 Leader 투표 기능을 통해, Active NameNode를 선출하는 기능이라고 정리하였습니다. Q1. 시간 순으로 어떻게 되는지가 헷갈립니다. 주키퍼를 통해 상시 모니터링을 하다가, 해당 이슈가 발생할 시, 재빠르게 Active Node로 전환이 되고 나서, 해당 Split Brain 이슈가 발생하며 데이터 충돌이 발생했던 부분을 QJM에서 다수결 원칙을 통해, 올바르지 않은 Journal Node에 있는 데이터는 삭제하며, 데이터의 일관성을 유지한다는 것일까요? Q2. 만약에 Active Node로 전환이 이루어졌는데도, 해당 문제가 지속적으로 해결이 되지 못해서, QJM에서 다수결 원칙을 통해 해결을 못하는 상황이 발생하면, 심각한 문제상황이라고 볼 수 있는건가요? 잘못 설계해서, 삭제된 데이터는 복구를 할 수 없는건가요? Q3. Network File System의 경우 hdfs-site.xml에 fencing을 추가함으로써, Split Brain issue를 해결할 수 있다고 공부할 수 있었습니다. 그런데, 상기 방법이 있는데도 불구하고, QJM 방식을 사용하는 이유는, 일정정도 해당 문제가 발생할 시, 데이터의 정합성을 보장해준다는 부분 때문에 차용하는 것일까요?
-
미해결
안드로이드 스튜디오 깃허브 연결 관련 도와주세요..
깃허브에서 프로젝트를 가져와서 실행하는 경우에 잘 되던 코드들이 안되면서 sdk파일이 없다고 나오고 pub get 이 안됩니다..
-
미해결자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)
소문자로 바꾼후에 reverse를 통해서 구해보았습니다
감사합니다.function solution(args) { return args.toLowerCase().split("").join("") === args.toLowerCase().split("").reverse().join("") ? "YES" : "NO"; } console.log(solution("gooG"));
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
new 와 그냥 클래스 차이에 대한 추가 질문
코팩님 강의 잘보고있습니다. :) 'DefaultValuePipe 사용해보기'라는 강의에서 궁금한 것이 있어서 질문드립니다.new와 그냥 클래스는 제가 이해한 바로는 그냥 클래스처럼 넣게 되면 DI를 통한 nest에서 싱글톤 패턴으로 ParseIntPipe를 주입해주는 것이고 new키워드를 붙이게 되면 인스턴스가 생성하게 됨으로 nest에서 DI로 주입해주는 것이 아닌 ParseIntPipe클래스의 인스턴스가 생성되는 방식인가요?감사합니다.
-
해결됨외워서 끝내는 네트워크 핵심이론 - 기초
패킷이 단편화가 일어날 때 TTL은 어떻게 되나요?
패킷이 단편화가 일어나 2개 이상으로 쪼개질 경우 TTL은 단편화 전 패킷이 갖고 있던 카운트가 그대로 유지가 되나요? 아니면 새로운 카운트가 적용이 되는걸까요? 쪼갠 패킷에 같은 목적지 IP헤더를 만들어 쪼갠 정보를 붙여넣기 한다는데 TTL은 어떻게 되는지 궁금해서 여쭤봅니다... 제가 생각해봤을 때는 PC에서 패킷을 보낼 때 헤더에 TTL이 미리 지정되어 있고 단편화가 된 패킷들이 같은 패킷인걸 구분하고 목적지에서 조립을 하려면 최대한 같은 경로로 이동하는 것이 효율적이라 그대로 유지가 될 거라고 생각합니다...
-
미해결입문자를 위한 자바스크립트 기초 강의
로또 번호 추첨기 과제 만들기 중
// 요소 선택 및 상수 선언 let lottoEl = document.querySelector('.lotto'); let numbersDiv = lottoEl.querySelector('.numbers'); let drawButton = lottoEl.querySelector('#draw');// 추첨 let resetButton = lottoEl.querySelector('#reset');// 다시 let lottoNumbers = []; // 6개의 추첨 번호가 들어갈 배열 let colors = ['#d44052','#F5A623','#F5E123','#7ED321','#4A90E2','#4A53E2']; let paintNumber = (num) => { let eachNumDiv = document.createElement('div'); let colorIndex = Math.floor(num/10); eachNumDiv.classList.add('eachnum'); eachNumDiv.style.backgroundColor = colors[colorIndex]; numbersDiv.appendChild(eachNumDiv); } function drawNum(){ // ran 변수가 여기 위치에 위치하면 자꾸 무한루프에 빠짐 ;ㅁ; //무한루프 발생 주의 let ran = Math.floor(Math.random()*44)+1; while(lottoNumbers.length < 6) { //let ran = Math.floor(Math.random()*44)+1; if(lottoNumbers.indexOf(ran) === -1){ lottoNumbers.push(ran); paintNumber(ran); } } } function clearNum(){ lottoNumbers.splice(0,6); numbersDiv.innerHTML = ''; } drawButton.addEventListener('click', drawNum); resetButton.addEventListener('click', clearNum); 예제코드 무한루프 코드 입니다. 실행 시 무한 루프 발생합니다. 과제 하던 중 무한루프를 만났습니다.이 경우 변수가 밖에 있으면서 while의 조건문이 충족되지 못해서 무한 루프가 만들어지는 경우가 맞을까요?