묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨토비의 스프링 부트 - 이해와 원리
복잡한 decorator 예제
안녕하세요 토비님! 강의를 듣는 중에, 여러개의 데코레이터를 우선순위를 정하는 방법 말고 원하는 상황에 맞게 주입이 되도록 처리하는 방식에 대해 말씀해주셨는데, 해당 방법에 대해 좀더 자세하게 알고 싶어져서 사용하는 예제 코드를 구글링 해보았지만 못찾겠어서 질문 올립니다.
-
미해결Vue.js + TypeScript 완벽 가이드
프로젝트 권한 요청 드립니다.
첫번째 두번째 프로젝트 권한 요청 드립니다. 인프런 계정 : parkjungwoo2000깃허브 계정 : myjungwu 감사합니다.
-
미해결실전! Querydsl
SpringBoot 3.0.2 버전 QueryDSL 설정문제
[질문 내용]안녕하세요. 수강생 김땡땡이라고 합니다.추가로 작성해주신 Spring 3.0 버전 설정을 적용해서 build.gradle을 작성했는데 아래와 같은 에러가 발생하면서 테스트 에러가 발생합니다. 먼저 강의내용과 수업자료를 통해서 Springboot 3.0 이상 버전에서 설정해야되는 부분들을 추가했습니다. javax관련 오류는 뜨지 않습니다. 하지만 다른 문제가 생겼는데요.. gradle >other >compileQuerydsl 을 실행하면, 문제점이 있습니다. compileQuerydsl을 통해서 생성되는 Q Class는 build 경로에만 생기고 src/main에는 생성이 되지 않는다.<build 경로 아래에는 성공적으로 Qclass 가 생성되었습니다.>하지만 src/main아래에는 생성되지 않았네요.. 그래도 build 경로아래에 QClass가 생성되어있으니 간단한 Test는 될 것 같아서 수업 내용을 따라서 작성하고 실행해봤는데. 위와 같은 에러가 발생했습니다. Qclass를 찾지못해 발생하는 오류같은데.. 왜 이런 현상이 생기는지 모르겠습니다. 강사님과 똑같이 작성했는데.. 단순 버전 문제일까요? 이런경우엔 gradle 버전도 상관이 있는건가요? 현재 사용하는 gradle 버전은 확인해보니 7.6입니다. 검색을 많이 해봐도 해결방안이 나오질 않습니다. 도움 부탁드립니다. =======================저의 build.gradle 설정========================plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'study' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' // Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } //querydsl 추가 시작 def querydslDir = "$buildDir/generated/querydsl" querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } configurations { querydsl.extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl } //querydsl 추가 끝 ======================= Hello Entity =============================package study.querydsl.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter public class Hello { @Id @GeneratedValue private Long id; }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
수정 페이지 마운트 직후, 온체인지 핸들러가 인풋 값을 ""으로 인식하여, 인풋 값를 지웠을 경우, 온체인지 핸들러가 값의 변동을 인식하지 못하는 문제가 있습니다.
안녕하세요 강의 잘 보고있습니다.수정 페이지 마운트 직후, 온체인지 핸들러가 인풋 값을 ""으로 인식하고, 인풋 값를 지웠을 경우, 온체인지 핸들러가 값의 변동을 인식하지 못하는 문제가 있습니다.즉, 수정 페이지의 각 인풋 디폴트 값들에 데이터가 불러와진 후, 값을 입력하는 것이 아니라 삭제할 경우에 값의 변동을 온체인지 핸들러가 인식하지 못하여 발생합니다.따라서, 인풋의 온체인지 핸들러를 통해 인풋 값들이 비어있는지 확인하는 유효성 검사에 작은 오류가 있습니다. 수정페이지 마운트 직후 데이터를 불러온 뒤, 값이 인풋에 입력된 후, 온체인지핸들러가 변동을 인식하게 할 수 있을까요? 혹시 비슷한 인풋 값들을 객체에 묶어 저장하는 방식을 지양해야 할까요? import { type ChangeEvent, useState, useRef, useEffect } from 'react'; import { useRouter } from 'next/router'; import BoardWrite_presenter from './BoardWrite_presenter'; import { CREATE_BOARD, UPDATE_BOARD, UPLOAD_FILE } from './BoardWrite_queries'; import { useMutation, useQuery } from '@apollo/client'; import { type IBoardWrite_container_Props, type IUpdatedVariables, } from './BoardWrite_types'; import { type Address } from 'react-daum-postcode/lib/loadPostcode'; import { checkFileValidation } from '../../commons/checkFileValidation'; import { Modal, Spin } from 'antd'; import type { RcFile } from 'antd/es/upload'; import type { UploadFile } from 'antd/es/upload/interface'; import { getBase64 } from '@/src/commons/utils/utils'; import { FETCH_BOARD } from '../detail/BoardDetail_queries'; import { type IQuery } from '@/src/commons/types/generated/types'; import { Loading3QuartersOutlined } from '@ant-design/icons'; export default function BoardWrite_container( props: IBoardWrite_container_Props ) { const router = useRouter(); const boardId = router.query.boardId; if (props.isEditing && !boardId) { return ( <Spin indicator={<Loading3QuartersOutlined spin />} /> ) } const { data } = useQuery<Pick<IQuery, 'fetchBoard'>>(FETCH_BOARD, { variables: { boardId, }, }); const fetchBoard = data?.fetchBoard; if (props.isEditing && !boardId && !fetchBoard) { return ( <Spin indicator={<Loading3QuartersOutlined spin />} /> ) } const [createBoard] = useMutation(CREATE_BOARD); const [updateBoard] = useMutation(UPDATE_BOARD); const [images, setImages] = useState('youtube'); const [isOpen, setIsOpen] = useState(false); const [writerError, setWriterError] = useState(false); const [passwordError, setPasswordError] = useState(false); const [titleError, setTitleError] = useState(false); const [contentsError, setContentsError] = useState(false); const [valid, setValid] = useState(false); interface ICoreInput { [key: string]: string writer: string password: string title: string contents: string } const [coreInput, setCoreInput] = useState<ICoreInput>({ writer: fetchBoard?.writer ?? '', password: '', title: fetchBoard?.title ?? '', contents: fetchBoard?.contents ?? '' }) const [coreInputErorr, setCoreInputErorr] = useState({ writer: false, password: false, title: false, contents: false }) useEffect(() => { if (fetchBoard) { setCoreInput({ ...coreInput, writer: String(fetchBoard.writer), title: String(fetchBoard.title), contents: String(fetchBoard.contents), }) } }, [data]) const onChangeCoreInput = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { setCoreInput({ ...coreInput, [e.currentTarget.id]: e.currentTarget.value }); setCoreInputErorr({ ...coreInputErorr, [e.currentTarget.id]: false }); const AllInputs: string[] = []; for (const prop in coreInput) { if (prop !== e.currentTarget.id) { AllInputs.push(coreInput[prop]) } else { AllInputs.push(e.currentTarget.value) } } console.log("AllInputs : " + AllInputs) if (!AllInputs.includes('' && "undefined")) { setValid(true); } else setValid(false); }; const onChangeImages = (e: ChangeEvent<HTMLInputElement>) => { setImages(e.target.value); }; const [input, setInput] = useState({ zipcode: "", address: "", addressDetail: "", youtubeUrl: "" }) const onChangeInput = (e: ChangeEvent<HTMLInputElement>) => { setInput({ ...input, [e.target.id]: e.target.value }); }; const onSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault(); if (coreInput.writer === '') { setWriterError(true); } if (coreInput.password === '') { setPasswordError(true); } if (coreInput.title === '') { setTitleError(true); } if (coreInput.contents === '') { setContentsError(true); } if (coreInput.writer && coreInput.password && coreInput.title && coreInput.contents) { try { const result = await createBoard({ variables: { createBoardInput: { writer: coreInput.writer, contents: coreInput.contents, password: coreInput.password, title: coreInput.title, youtubeUrl: input.youtubeUrl, images, boardAddress: { zipcode: input.zipcode, address: input.address, addressDetail: input.addressDetail, }, }, }, }); void router.push(`/boards/${result.data.createBoard._id}`); } catch (error) { if (error instanceof Error) alert(error.message); } } }; const onUpdate = async (e: { preventDefault: () => void }) => { e.preventDefault(); const updatedVariables: IUpdatedVariables = { boardId, password: coreInput.password, updateBoardInput: { contents: coreInput.contents, title: coreInput.title, youtubeUrl: input.youtubeUrl, images, boardAddress: { zipcode: input.zipcode, address: input.address, addressDetail: input.addressDetail, }, }, }; if (!coreInput.password) { setPasswordError(true); } if (!coreInput.title) { setTitleError(true); } if (!coreInput.contents) { setContentsError(true); } if (!coreInput.password && !coreInput.title && !coreInput.contents) { try { const result = await updateBoard({ variables: updatedVariables, }); void router.push(`/boards/${result.data.updateBoard._id}`); } catch (error) { if (error instanceof Error) alert(error.message); } } }; const onToggleModal = () => { setIsOpen((prev) => !prev); }; const handleComplete = (data: Address) => { let fullAddress = data.address; let extraAddress = ''; if (data.addressType === 'R') { if (data.bname !== '') { extraAddress += data.bname; } if (data.buildingName !== '') { extraAddress += extraAddress !== '' ? `, ${data.buildingName}` : data.buildingName; } fullAddress += extraAddress !== '' ? ` (${extraAddress})` : ''; } setInput({ ...input, address: fullAddress, zipcode: data.zonecode }); onToggleModal(); }; const [uploadFile] = useMutation(UPLOAD_FILE); const [imgUrl, setImgUrl] = useState("") const fileRef = useRef<HTMLInputElement>(null) const onClickFile = () => { fileRef.current?.click() } const onChangeFile = async (e: ChangeEvent<HTMLInputElement>) => { const file = e.target.files?.[0]; const isValid = checkFileValidation(file); if (!isValid) { return } if (isValid) { try { const result = await uploadFile({ variables: { file } }) setImgUrl(result.data?.uploadFile.url) } catch (error) { if (error instanceof Error) { Modal.error({ content: error.message }) } } } } const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(''); const [previewTitle, setPreviewTitle] = useState(''); const [fileList, setFileList] = useState<UploadFile[]>([]); const handleCancel = () => { setPreviewOpen(false); }; const handlePreview = async (file: UploadFile) => { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj as RcFile); } setPreviewImage(file.url ?? (file.preview as string)); setPreviewOpen(true); setPreviewTitle(file.url ? (file.name || file.url.substring(file.url.lastIndexOf('/') + 1)) : ""); }; return ( <BoardWrite_presenter onChangeInput={onChangeInput} onChangeCoreInput={onChangeCoreInput} onChangeImages={onChangeImages} writerError={writerError} passwordError={passwordError} titleError={titleError} contentsError={contentsError} zipcode={input.zipcode} address={input.address} onSubmit={onSubmit} onUpdate={onUpdate} valid={valid} isEditing={props.isEditing} data={data} isOpen={isOpen} handleComplete={handleComplete} onToggleModal={onToggleModal} imgUrl={imgUrl} onClickFile={onClickFile} onChangeFile={onChangeFile} fileRef={fileRef} fileList={fileList} handlePreview={handlePreview} setFileList={setFileList} previewOpen={previewOpen} previewTitle={previewTitle} handleCancel={handleCancel} previewImage={previewImage} /> ); } import { Button, Image, Modal, Upload } from 'antd'; import DaumPostcodeEmbed from 'react-daum-postcode'; import { Main, Title } from '../../../commons/styles/emotion'; import * as S from './BoardWrite_styles'; import { type IBoardWrite_presenter_Props } from './BoardWrite_types'; import type { UploadProps } from 'antd/es/upload'; import { PlusOutlined } from '@ant-design/icons'; export default function BoardWrite_presenter( props: IBoardWrite_presenter_Props ) { const valid = props.valid; const isEditing = props.isEditing; const data = props.data?.fetchBoard; const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { props.setFileList(newFileList); }; const uploadButton = ( <div> <PlusOutlined /> <div style={{ marginTop: 8 }}>Upload</div> </div> ); return ( <Main> <S.Form> <Title>게시물 {isEditing ? '수정' : '등록'}</Title> <div className="writer"> <S.InputWrapper> <label>작성자</label> <input id="writer" onChange={props.onChangeCoreInput} type="text" placeholder="이름을 입력해주세요." defaultValue={props.data?.fetchBoard.writer ?? ""} readOnly={!!props.data?.fetchBoard.writer} /> {props.writerError && ( <p className="alert">이름을 입력해주세요.</p> )} </S.InputWrapper> <S.InputWrapper> <label>비밀번호</label> <input id="password" onChange={props.onChangeCoreInput} autoComplete="off" type="password" placeholder="비밀번호를 입력해주세요." defaultValue={``} /> {props.passwordError && ( <p className="alert">비밀번호를 입력해주세요.</p> )} </S.InputWrapper> </div> <S.InputWrapper> <label>제목</label> <input id='title' onChange={props.onChangeCoreInput} type="text" placeholder="제목을 작성해주세요." defaultValue={data?.title} /> {props.titleError && ( <p className="alert">제목을 작성해주세요.</p> )} </S.InputWrapper> <S.InputWrapper> <label>내용</label> <textarea id='contents' onChange={props.onChangeCoreInput} placeholder="내용을 작성해주세요." defaultValue={props.data?.fetchBoard.contents} /> {props.contentsError && ( <p className="alert">내용을 작성해주세요.</p> )} </S.InputWrapper> <S.InputWrapper> <label>주소</label> <div className="zipcode"> <input id="zipcode" onChange={props.onChangeInput} type="text" // placeholder="00000" readOnly value={ props.address || (props.data?.fetchBoard.boardAddress?.address ?? "") } /> <button onClick={(e) => { e.preventDefault(); props.onToggleModal(); }} > 우편번호 검색 </button> {props.isOpen && ( <Modal title={'우편번호 검색'} open={props.isOpen} onOk={props.onToggleModal} onCancel={props.onToggleModal} > <DaumPostcodeEmbed onComplete={props.handleComplete} ></DaumPostcodeEmbed> </Modal> )} </div> <input id='address' onChange={props.onChangeInput} className="address" type="text" readOnly value={props.address !== "undefined" ? props.address : ""} /> <input id='addressDetail' onChange={props.onChangeInput} type="text" defaultValue={ data?.boardAddress?.addressDetail ? data?.boardAddress?.addressDetail : '' } /> </S.InputWrapper> <S.InputWrapper> <label>유튜브</label> <input id='youtubeUrl' onChange={props.onChangeInput} type="text" placeholder="링크를 복사해주세요." defaultValue={ data?.youtubeUrl ? data?.youtubeUrl : '' } /> </S.InputWrapper> <S.InputWrapper> <label>사진업로드</label> <Button onClick={props.onClickFile}>사진 업로드</Button> <input style={{ display: "none" }} ref={props.fileRef} onChange={props.onChangeFile} type="file" /> </S.InputWrapper> {props.imgUrl && <Image src={`https://storage.googleapis.com/${props.imgUrl}`}></Image>} <S.InputWrapper> <label>사진 첨부</label> <Upload // action="https://www.mocky.io/v2/5cc8019d300000980a055e76" listType="picture-card" fileList={props.fileList} onPreview={props.handlePreview} onChange={handleChange} > {props.fileList.length >= 8 ? null : uploadButton} </Upload> <Modal open={props.previewOpen} title={props.previewTitle} footer={null} onCancel={props.handleCancel}> <img alt={props.previewTitle} style={{ width: '100%' }} src={props.previewImage} /> </Modal> </S.InputWrapper> <S.InputWrapper> <div className="radios"> <span> <input type="radio" id="youtube" name="radios" value="youtube" defaultChecked onChange={props.onChangeImages} /> <label htmlFor="youtube">유튜브</label> </span> <span> <input type="radio" id="image" name="radios" value="image" onChange={props.onChangeImages} /> <label htmlFor="image">사진</label> </span> </div> </S.InputWrapper> <S.SubmitButton onClick={isEditing ? props.onUpdate : props.onSubmit} valid={valid} disabled={!valid} > {isEditing ? '수정하기' : '등록하기'} </S.SubmitButton> </S.Form> </Main> ); }
-
미해결[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
Error: Not found: 'dart:ffi' 에러
안녕하세요 에러문제로 골머리를 앓다가 질문합니다색상정보 DB에 넣기를 따라하면서 db를 만들고 색상 쿼리를 넣고 문제없이 따라 코딩했지만 처음보는 에러를 보고 혼자 해볼려고 노력했지만 안되네요 ㅠㅠimport 'dart:ffi' 여기에서 Error: Not found: 'dart:ffi' 이 종류의 에러가 나와서 크롬으로 앱이 실행이 안되네요 ㅠㅠ어떤 문제일까요? 사진첨부합니다
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
MVC패턴 - 적용 목차에서 적용한 MVC패턴 관련해서 질문드립니다
서블릿, JSP, MVC패턴 목차에서 구현한 MVC패턴이구조 상으로는 별도의 레포지토리와 서비스가 없이 컨트롤러 안에 비즈니스 로직이 구현되어서 강의자료 상의 MVC패턴 1인 것 같은데요앞으로 진행하는 MVC 프레임워크 만들기가 이 MVC 패턴 1을 기반으로 진행되는 것이 맞을까요?강의 상에서는 MVC패턴 1이 아니라 2가 원래의 MVC 모델이라고 말씀해 주셨었는데MVC패턴 2로 구성하시지 않은 이유가 무엇인지 알고 싶습니다.
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
Axios로 API 요청시 에러
Axios로 아래와 같이 요청시 Object가 안나오고 에러가 발생합니다.에러내용은 아래와 같습니다참고로 MySQL 데이터는 아래와 같습니다.Axios dummy 테스트는 문제가 없었는데, Network Error는 뭘까요?
-
미해결홍정모의 따라하며 배우는 C++
안녕하세요 위임 생성자 강의를 듣는 도중에 궁금한 점이 생겼습니다.
위임 생성자가 매개변수에 값을 입력 안했을 때, 클래스를 다시 참조해서 사용자가 입력한 값을 인스턴스에서 출력하는 것이잖아요?? 가령, Student(const string& name_in) : Student(0, name_in) {} 와 같이요.그런데 잘 생각해보면 디폴트 매개변수 생성자도 매개변수에 미리 값을 설정해주고, 인스턴스 인자에 값을 안넣어주면 디폴트값을 출력하는 것도 같은 원리인데 차이점이 무엇인가요??
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
6:44쯤에 EntityGraph의 옵션으로 attributePath로 놓는 게 좋지 않다고 하셨는데 그 이유가 궁금합니다.
안녕하세요. 기선님이 알려주신 팁들로 많은 성장을 하고 있습니다. 감사합니다. 다름이 아니라, 6:44 쯤에 attributePaths로 옵션을 다 변경하시면서 "이게 안 좋다고" 말씀하셨습니다.기존에 EntityGraph의 옵션으로 value를 주면서 Entity 클래스에도 책임이 많아진 터라, 이 소스를 줄이면서 엔티티 클래스의 책임이 덜어져서 더 좋지 않나? 라고 생각하거든요. 혹시 다른 성능상의 이유라도 있을까요? 다른 엔티티 클래스에도 저런 머리 위에 어노테이션(책임)들을 줄이면 코드를 더 깔끔하게 보면서 EntityGraph를 더 잘 활용할 수 있지 않을까 생각합니다. 기선님의 의견을 듣고 싶습니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
@RequestParam 질문드립니다
========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@GetMapping("hello-string") @ResponseBody public String helloString(@RequestParam("name") String name1){ return "hello"+name1; }위와 같은 코드와 url에서 localhost:8080/hello-string?name=springboot를 입력받았을 때파라미터 name은 key값으로서 value값인name1과 바인딩 되어 name1에 springboot를 저장 하기위한 용도로 사용되는 건가요? 다른 시각으로 name1을 key값로 springboot를 value값 생각해도 되는건가요?name - name1 - springboot(key) - (value)................(key) - (value)즉, 이렇게 이해해도 되는건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
컨트롤러에서 레포지토리를 호출할 때 의존성
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]여기에 질문 내용을 남겨주세요.주문 목록 검색, 취소 강의 2분 20초 즈음에 함수위임 정도의 간단한 행동은 컨트롤러에서 직접 호출하는 것도 고려해도 괜찮다라고 하셨는데, 이는 즉 컨트롤러가 레포지토리를 바로 의존하는 상황이여도 상황에 따라서는 괜찮다고 이해하여도 괜찮을까요 ?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Server Error Error: '@next/font' is only available in Next.js 13 and newer. 오류
이러한 오류떄문에 지금 만든 게시판등록 페이지가 실행이안됩니다 포트폴리오 01
-
미해결윤재성의 자바 기반 안드로이드 앱개발 Part 2 - 메뉴와 4대 구성요소
onCreateOptionsMenu return 값 질문 !
onCreateOptionsMenu 메소드의 return 값을 false로 변경하고 재실행 여러번 했는데 옵션 메뉴가 안사라지더라고요 혹시 버그일까요 ?
-
미해결[리뉴얼] 처음하는 파이썬 데이터 분석 (쉽게! 전처리, pandas, 시각화 전과정 익히기) [데이터분석/과학 Part1]
groupby().sum() 사용 특정 컬럼 기준으로 데이터 합치기 관련
안녕하세요!강의 2:24 에서,Groupby('Country_Region').sum() 사용시 다른 컬럼의 값들을 'Country_Region' 컬럼의 값을 기준으로 데이터를 합치게 되는데,Lat이나 Long_과 같이 데이터를 단순 Sum을 하면 안되는(?) 것들은 어떻게 처리가 되는건가요?
-
해결됨뉴욕 프로덕트 디자이너가 알려주는, 입문자를 위한 UX디자인 개론
좋은 UX와 안좋은 UX 사례
안녕하세요! 제가 자주 사용하는 컬리와, 오늘의집 두가지 앱으로 과제 제출합니다. 이전 검색 결과에 따라 상품추천 해주던 것이 생각나 선택하게되었어요. 식품, 인테리어 각 다른 분야의 서비스지만, 두 앱 모두 맞춤형 콘텐츠를 추천하는 개인화 서비스를 제공하고 있었는데요. 이외에도 두 앱을 비교하며 여러 공통점으로 찾아 볼 수 있었습니다. 배웠던 UX입문 원리들에 따라 분류해보았습니다.1.낮은의도와 높은 의도를 가진 사용자를 고려한 콘텐츠 구성 공통적으로 검색데이터를 활용한 추천상품(이 상품 어때요?/최근관심있게본#00)과 사용자의도를 고려한 메뉴구성이 눈에 띄었는데요. 추천상품(컬리추천/취향의발견), 혜택상품(알뜰쇼핑, 특가혜택/오늘의 딜)이 공통적인 특징이라 생각했습니다.또 하나 공통적으로 컬리는 ‘컬리로그’의 요리•뷰티와 관련한 일상사진으로 오늘의 집은 ‘커뮤니티’의 집들이 소개 콘텐츠로 상품을 간접노출 하고 있습니다. 다만 오늘의 집 경우 이벤트 영역 아래 사용자가 자주 찾을 법한 메뉴를 아이콘으로 구성해 보여주어 한눈에 필요한 메뉴를 찾을 수 있다고 생각했습니다. 다음은 안좋은 UX사례로1.모바일앱과 PC웹의 다른 메뉴명 - 오늘의 집 어떤 이유가 있는 걸까요? 오늘의 집의 경우 PC웹에서 확인해보니 하위 콘텐츠는 동일한데 메뉴명이 다른 것을 발견했습니다. PC웹에서는 ‘커뮤니티’, ‘스토어’, ‘이사/시공/수리’로 최상위 메뉴구조를 앱의 경우는 커뮤니티를 ‘둘러보기’, 스토어를 ‘쇼핑’으로 보여주고 있었습니다. (사례를 찾을 당시는 스토어 였는데 글을 올리는 시점엔 쇼핑으로 변경되었네요 ?)앱 최상단에 검색바의 경우도 앱은 오늘의 집 통합검색, 쇼핑검색이고 PC는 통합검색과 스토어검색입니다. 이부분이 수업에서 배운 일관성의 원리에 어긋나는 것은 아닌지 해서 UX의 안좋은 사례로 선정하였습니다. 2.컬리의 마켓 or 뷰티 탭 전환 시 어딘가 불편한 UX 마켓컬리와 뷰티컬리의 탭전환은 네비게이션 바 가운데 토글 스위치 형태의 UI로 이루어집니다. 여기서 마켓과 뷰티의 전환 시 하단탭바의 가운데 아이콘 ‘메뉴’를 누르면 하위 메뉴들도 바뀌어있는 것을 알 수 있습니다. 두번째 메뉴인 컬리로그도 탭 전환에 따라 전체 페이지 내 요리와 뷰티 중 해당하는 콘텐츠가 상위에 노출 되는 것 같습니다. (여러번 마켓과 뷰티를 전환해봄) 최상위 메인기능 전환이 이루어지는 하단탭바에 컬리의 탭 (마켓or뷰티)을 붙이다보니 UX적으로 아쉽다고 생각했습니다. 여기서 탭바의 메뉴구조를 조금 손보면 사용자의 혼선을 줄일 순 있지않을까.. 생각해보기도 했습니다. (홈을 가운데 정렬하고 좌우로 기타 메뉴를 배치한 후 컬리탭을 홈으로 전환한다면..) 현재 앱에서 상단과 우측 하단 두 곳에 전환 탭을 중복 제공하고 있는데 어쩌면 엄지영역을 고려해 한 화면에 두곳이나 중복으로 배치한 것이 아닌지 추측해보았습니다.읽어주셔서 감사합니다.
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
3-A 반례를 알고 싶습니다
http://boj.kr/2ee36f4f84574c92a5029deb708602c6일반 가정 집과 치킨 집 좌표를 구해두고 거리를 구한 다음 y에는 가정집 기준, x에는 치킨집 기준의 거리를 2차원 vector d에 넣어줬습니다.최소값을 구해야하기 때문에 같은 x의 y값( 즉, 치킨집을 기준으로 모든 집과의 거리)의 합을 구하여 v vector에 넣었습니다. v는 <치킨집번호, 총거리의합>으로 담았습니다.--> 이제 v[1].first에는 1번 치킨집이라는 정보, v[1].second에는 1번 치킨집과 모든 집과의 거리의 합이 들어가게 됩니다.v를 v.second(치킨집과 각 집의 총거리의 합)를 비교하는 함수로 sort하고 m만큼 반복(입력한 남아 있을 최대 치킨 집의 수) 가정집과 first(치킨집번호)에 해당하는 거리를 min 함수를 이용하여 최소값을 구한 뒤 ret에 더해줍니다.TC 모두 통과하기도 했고 논리적으로 오류가 없다고 생각했는데 틀렸다고 하여 반례 질문드립니다! 설명이 너무 장황했다면 죄송합니다ㅜ
-
해결됨나도코딩의 자바 기본편 - 풀코스 (20시간)
Thread 질문
선생님이 하신거랑 똑같이 했는데 저는 컴파일결과가 사장청소와 직원청소가 섞여서 안나오네요... package chap_12; import chap_12.clean.CleanThread; public class _01_Thread { public static void main(String[] args) { // 하나의 프로세스 (Process) // 쓰레드 (Thread) // 1 3 5 7 9 // ---복도--- // 2 4 6 8 10 // cleanBySelf(); CleanThread cleanThread = new CleanThread(); // cleanThread.run(); // 직원 청소 cleanThread.start(); cleanByBoss(); // 사장 청소 } public static void cleanBySelf() { System.out.println("-- 혼자 청소 시작 --"); for (int i = 1; i < 10; i++) { System.out.println("(혼자) " + i + "번방 청소 중"); } System.out.println("-- 혼자 청소 끝 --"); } public static void cleanByBoss() { System.out.println("-- 사장 청소 시작 --"); for (int i = 1; i <= 10; i += 2) { System.out.println("(사장) " + i + "번방 청소 중"); } System.out.println("-- 사장 청소 끝 --"); } } package chap_12.clean; public class CleanThread extends Thread { public void run() { System.out.println("-- 직원 청소 시작 (Thread) --"); for (int i = 2; i <= 10; i += 2) { System.out.println("(직원) " + i + "번방 청소 중 (Thread)"); } System.out.println("-- 직원 청소 끝 (Thread) --"); } } ------------ 결과 --------------------- -- 사장 청소 시작 -- (사장) 1번방 청소 중 (사장) 3번방 청소 중 (사장) 5번방 청소 중 (사장) 7번방 청소 중 (사장) 9번방 청소 중 -- 사장 청소 끝 -- -- 직원 청소 시작 (Thread) -- (직원) 2번방 청소 중 (Thread) (직원) 4번방 청소 중 (Thread) (직원) 6번방 청소 중 (Thread) (직원) 8번방 청소 중 (Thread) (직원) 10번방 청소 중 (Thread) -- 직원 청소 끝 (Thread) -- Process finished with exit code 0
-
미해결U-Net 구현으로 배우는 딥러닝 논문 구현 with TensorFlow 2.0 - 딥러닝 의료영상 분석
성능평가관련해서 질문좀 드리겟습니다
강사님 안녕하세요 성능평가관련해서 질문좀 드리겟습니다 . 일반적으로 세그멘테이션은 accurary보다 mAP 혹은IOU로 평가하는걸로 아는데 그럼 아래코드 metrics = ["accurary"]를 어떻게 바꾸어야 하는지요?바쁘시겟지만 조언 좀 부타드리겟습니다 ㅎ unet_model.compile(optimizer = optimizer, loss = binary_loss_object, metrics = ["accurary"])
-
미해결Slack 클론 코딩[실시간 채팅 with React]
key prop 에러
Workspace에서 {channelData?.map((v) => ( <div>{v.name}</div> ))}콘솔에서 이 부분 때문에 key prop 에러가 나는 것 같은데 나중에 ChannelList로 바꿀꺼라서 신경 쓰지 않아도 되는 부분인가요??
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
5-T 낚시왕 질문있습니다..
안녕하세요 선생님,매번 선생님 정답코드 보기전에 먼저 충분히 코딩해보고 안되면 정답보는 식으로 수업을 듣고있습니다.이번 낚시왕 문제같은경우 상어가 움직이는 로직을 좀더 신경써서 나름 코딩을 했고, Test Case와 개시판 모든 반례들을 다 통과했는데, 제출하자마자 바로 틀렸다고 나오네요..제가 무엇을 놓치고 있는지 알려주시면 감사합니다.선생님이 강의해주신 논리가 비슷한거같은데 제 코드는 제대로 계산하지 못한 반례가 있을까요..?http://boj.kr/504e729dba00420a807fdcc3a57d2fde 항상 좋은 강의 감사합니다 ㅠㅜ