블로그

김찬희

[인프런 워밍업 클럽 스터디] 1기 첫번째 발자국

회고록 독학으로 공부를 하다보니 자기 객관화와 지금까지 뭔가 프로젝트를 처음부터 끝까지 완성해본 경험이 없고 부족하다는 생각이 들어서 무작정 신청하게 되었다. 처음에는 아 그냥 간단한 게시판 구현해보고 이후에 내가 기능 몇가지 추가해서 프로젝트 구현 하면 되겠다 정도로 가볍게 생각하고 들었던 강의였는데 강의를 하나씩 듣다보니 이전에 학습했던 내용들이 조립되는 느낌이 들어서 정말 개발에 흥미를 붙일 수 있었던 시간이었다. 사실 spring에 대해서 학습하다보면 전체적인 흐름을 놓치게 될때가 종종 있는거 같다. 스프링의 역사가 긴 만큼 하나의 기술에 대해 깊이 있게 파다보면 주변의 다른 기술과의 연결성을 잃을수 있다고 생각하는데 이 강의에서는 그 연결성에 대한 부분을 학습할 수 있어서 성장하는데 도움이 되었다.라이브러리 VS 프레임워크  라이브러리 : 프로그래밍을 개발할 때 만들어져 있는 기능을 가져다 사용하는 것 프레임워크 : 프로그래밍을 개발할 때 미리 만들어져 있는 구조에 코드를 가져다 끼워 넣는 것이때 강의에서는 요리에 비유를 했는데 김치 찌개를 만들때 라이브러리는 김치를 마트에서 가져오는 것, 프레임워크는 김치찌개 원데이 클래스에가서 만드는 것 이라는 설명이 이해하기 쉽게 와닿았다.@Annotation@SpringBootApplication : 스프링을 실행시키기 위해 필요한 다양한 설정들을 모두 자동으로 해주는 Annotation이다.@Annotation에 대한 추가 학습을 통해 개인블로그에 정리해보았다.https://velog.io/@chanheekim125/Annotation 네트워크란?네트워크 : 인터넷 주소 체계 ( 무언가(정보)를 전달할 때 필요한 체계)IP : 컴퓨터별로 갖는 고유 주소 ( ex) 244.69.51.9 ) 처럼 표시한다.DNS : 우리가 사이트에 접속할때 244.54.21.2 를 기억하고 입력할 수는 없으니까 ex) spring.com 등 이름을 사용PORT: 각 IP에는 여러가지의 프로그램을 사용하는데 이때 PORT 번호로 구분한다.HTTP와 API HTTP : 컴퓨터 간의 통신 표준 방식 ( 택배에서 운송장과 같은 개념 )HTTP 요청은 HTTP Method로 GET,POST가 주로 사용되며 PUT,DELETE 등이 있다.HTTP 요청에서 데이터를 전달하기 위해 쿼리(GET) 와 바디(POST)를 사용한다.이때 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다.API 개발하기 GET API POST API 직접 API 명세를 읽어보고 개발 해보면서 request를 받아서 데이터를 어떻게 처리하는지 알아보았다.https://velog.io/@chanheekim125/HTTP-API-%EA%B0%9C%EB%B0%9C데이터 베이스 이전 Section 에서는 그동안 Memory에 데이터를 저장하고 있었기 때문에 서버를 내리면 모든 데이터가 없어지는 현상이 발생했었다. 우리는 이러한 현상을 방지하기 위해 데이터를 DB에 SQL 문법을 사용해서 저장,조회,삭제,수정 하는 방법에 대해 학습하였다.SQL 문법은 정처기,SQLD 시험을 준비하면서 익숙했기에 개념보다는 MYSQL 실행툴에 익숙해 지는데 시간을 쓴거 같다. 정리 지금까지는 정말 기초라고 할수 있는 내용에 대해 학습해 보았다. 기본적인 API 기능을 구현할 수 있게 되었고 또, 무작정 강의만 수강해서 진도를 나가는 것이 아니라 과제를 하면서 스스로 동작 순서나 구현방법을 생각해보는 시간에 가장 많이 성장하는 나를 볼 수 있었다.

백엔드인프런워밍클럽StudyBE

코파

인프런 워밍업 클럽 1기 FE 4번 과제 (책 리스트 나열 앱)

4번 과제 (Day4)(책 리스트 나열 앱)깃허브 저장소 주소 :https://github.com/devellybutton/frontEnd_warmingUp_study/tree/master/04.%EC%B1%85%EB%AA%A9%EB%A1%9D기능 :'책 이름', '책 저자', '읽은 날짜'를 입력하고 버튼을 누르면 표 아래에 하나씩 등록이 됨.각 항목별로 수정, 삭제가 가능함. (연필: 수정, 디스켓: 수정완료)CSV 파일로 저장 가능함. (화면 맨 오른쪽 첫 번째 아이콘)리스트 내 전체 내용 삭제 가능함. (화면 맨 오른쪽 두 번째 아이콘)LocalStorage에 임시저장하여 페이지 로딩시 불러옴. (화면 맨 오른쪽 세 번째 아이콘) GIF:'책 이름', '책 저자', '읽은 날짜'를 입력하고 버튼을 누르면 표 아래에 하나씩 등록이 됨.각 항목별로 수정, 삭제가 가능함.LocalStorage에 임시저장하여 페이지 로딩시 불러옴.CSV 파일로 저장 가능함.리스트 내 전체 내용 삭제 가능함.  간단한 후기 :4개월간의 프론트엔드 부트캠프를 마치며 저는 기본적인 기능 구현 능력을 갖추게 되었습니다. 하지만 부끄럽게도 제대로 된 투두리스트 하나를 완성하지 못한 채 수료를 하여 큰 부족함을 느꼈습니다. 그래서 수정, 삭제 및 추가 기능까지 구현해 보았습니다.필요한 기능만 간단하게 구현하는 것과, 모든 기능을 완벽하게 구현하는 것의 차이를 절실히 느꼈습니다. 기능 추가 및 고도화를 통해 예상치 못한 문제들과 부딪히면서, 개발 속도가 크게 저하되는 것을 이번에 절실히 경험했습니다. 물론 실력이 부족한 것도 이유가 될 것입니다.인터넷에 있는 소스가 정말 많은데, 단순히 정보를 검색하고 코드를 복사하는 것이 아니라 본인의 프로젝트 상황에 맞게 적용하는 것이 중요하다고 생각하였습니다.항상 부족한게 보이는 데 시간이 적어서 고민이 됩니다. 처음에 생각한 기능들은 다 구현하였으나, 아직까지 다음과 같은 문제가 있습니다.1) CSS가 제대로 적용되지 않음. 2) CSV 파싱할 때 콤마(,)를 기준으로 하여서 책 이름이나 저자에 콤마가 들어갈 경우 문제가 발생함. 3) 짝수번째 표(tbody의 td)의 맨 마지막열 CSS 배경 제거 필요함.  트러블슈팅 :굵직하게 3개의 문제점이 있었습니다. 이벤트 위임버튼을 클릭하여 행을 삭제하려면 클릭 이벤트를 추가하여 행을 삭제하는 함수를 호출해야 하였습니다.각 항목 생성 후, row.innerHTML을 사용하면 행이 삭제될 때 HTML이 완전히 새로 고쳐지므로 이벤트 리스너도 함께 삭제되어 제대로 적용이 되지 않는 문제가 있었습니다.이때 버튼의 상위 요소에 클릭 이벤트 리스너를 추가하고, 클릭된 버튼에 따라 수행처리를 하여 해결하였습니다.수정 전 (위) / 수정 후 (아래)if (deleteBtn) { deleteBtn.addEventListener("click", (e) => { e.preventDefault(); removeBook(e); }); } // 책 목록 개별 삭제 function removeBook(e) { const row = e.target.closest("tr"); if (row) row.remove(); }table.addEventListener("click", (e) => { if (e.target.id === "delete-btn") { e.preventDefault(); removeBook(e); } }); // 책 목록 개별 삭제 function removeBook(e) { const row = e.target.closest("tr"); // 하위에 있는 tr 선택하도록 함 if (row) row.remove(); } 클래스의 초기화 방법 수정ConvertToCSV 클래스의 getCSV 메소드에서 tbody와 thead에서 tr을 모두 찾아 반환되어야 하였습니다.하지만 초기에 페이지 로딩 시에는 tbody에 내용이 없어서 이 메소드를 사용하여 tr을 찾으면 tbody에 있는 내용이 없는 상태이기 때문에 정상적으로 작동하지 않았습니다.이에 따라 이 클래스의 constructor에서가 아닌 내부 메소드에서 tr을 찾도록 수정하였습니다. 브라우저에서는 tbody의 td가 있는 상태이므로 이 방법으로 문제가 해결되었습니다.CSV 파일 생성 시 한글만 깨지는 오류Blob 객체를 생성할 때 type에 charset=UTF-8을 넣어 주지 않아, 한글이 깨진 것이 아닌가 생각하였습니다.하지만 charset=UTF-8을 넣어도 같은 문제가 발생하여 [csv]를 ["\uFEFF" + csv]로 변경하니 해결되었습니다. csvFile = new Blob([csv], { type: "text/csv; charset=UTF-8" }); downloadLink = document.createElement("a"); downloadLink.download = filename; 이미지 출처 :https://www.flaticon.com/free-icon/download_9153957?term=download&page=1&position=16&origin=search&related_id=9153957https://www.flaticon.com/free-icon/restart_6532052?term=reset&page=1&position=18&origin=search&related_id=6532052https://www.flaticon.com/free-icon/bookmark_10238285?term=bookmark&page=2&position=38&origin=tag&related_id=10238285개발할 때 참고한 링크 :https://beomi.github.io/2017/11/29/HTML-Table-to-CSV/https://stackoverflow.com/questions/31959487/utf-8-encoding-issue-when-exporting-csv-file-in-javascript

웹 개발워밍업클럽FE과제

임하스

[인프런 워밍업 스터디 클럽 1기] FE 1주차 발자국

시작공부하며 개인적으로 중요하다 생각하는 부분과 복습할 내용, 헷갈리던 부분들을 정리해보았다. 프레임워크와 라이브러리에 의존적이던 나를 되돌아보는 시간이었던 것 같다.  정리Console 객체console.log(...data: any[]): void 로그console.error(...data: any[]): void 에러console.warn(...data: any[]): void 경고console.table(tabularData?: any, properties?: string[]): void 객체 데이터를 테이블로 표기console.time(label?: string): void, console.timeEnd(label?: string): void 사이에 코드를 입력하여 속도 측정 가능. label을 넣어서 무엇에 대한 측정인지 설명을 달 수 있음console.count(label?: string): void, console.countReset(label?: string): void 호출된 횟수 반환(특정 데이터가 몇 번 호출됐는지) 변수의 참조 범위(scope)자바스크립트는 블록 레벨 스코프 호이스팅var, let, const 셋 다 호이스팅 됨근데 var는 선언과 undefined로 할당되기 때문에 참조가 가능하고, let과 const는 선언만 되고 할당되지 않음 자바스크립트 타입원시타입은 콜스택에 저장(불변성을 가짐)참조 타입 값은 힙에 저장값에 대한 주소는 콜스택에 저장원시타입 : Boolean, String, Number, null, undefined, Symbol참조타입 : Object, Array, functuon, classes, …자바스크립트는 동적 타입이다어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당(및 재할당) 가능배열(Array)은 typeof를 쓰면 obejct로 나오기 때문에, Array.isArray(변수) 메서드를 통해 배열인지 확인할 수 있다배열이 object 타입이라고 나오는 것이 잘못된 것이 맞는데, 공식에서도 이것을 인지하고 있지만 당시에 이미 object로 처리하여 개발한 곳들이 너무 많아서, 혼란을 일으키지 않기 위해 그대로 object로 두기로 했다고 한다 자바스크립트 타입 변환String(변수), 변수.toString() 차이Number(변수), parseInt(변수) 차이자바스크립트가 자동으로 변수 타입을 변경하는 기준(ex. string 타입 + number 타입 ⇒ string 타입) Loopsfor … in : 객체의 속성을 따라 반복 ⇒ 객체 순회객체의 열거 가능한 속성들을 반복할 때 사용됩니다.객체의 속성들을 순회하며 각 속성의 이름(키)을 반환합니다.일반적으로 객체의 속성을 순회할 때 사용되며, 배열을 순회할 때는 사용하지 않는 것이 좋습니다.for … of : 반복 가능한 객체를 반복 ⇒ 배열 순회반복 가능한(iterable) 객체(배열, 문자열, 맵, 셋 등)의 요소들을 반복할 때 사용됩니다.각 요소의 값을 반환합니다.객체의 속성을 직접 열거하지 않고 요소들을 순회할 때 사용됩니다.forEach() : void 타입, for 루프는 await과 함께 작동하지만 얜 아님.map() : return 필요for 루프가 forEach보다 빠름 Window 객체**window 객체**브라우저에서 제공하는 객체브라우저의 창(window)을 나타냄. 브라우저 창에 대한 정보를 알 수 있고, 제어도 가능var 키워드를 통해 변수를 선언하면 window 객체의 프로퍼티가 됨let과 const는 window 객체 내부의 블록에서 선언된 것 → 전역 객체의 프로퍼티로 활용될 수 없음DOM(Document Object Model)메모리에 웹 페이지 문서 구조를 트리 구조로 표현해서 웹 브라우저가 HTML 페이지를 인식하게 해주는 객체 모델window.documentBOM(Browser Object Model)웹 브라우저와 상호작용하는 데 사용되는 객체 모델window.location, window.history, window.navigator 등속성window.innerWidth 속성브라우저 창의 내부 너비컨텐트 영역의 너비콘솔창/스크롤 바가 있는 경우에는 이를 제외한 영역의 너비window.outerWidth 속성브라우저 창의 외부 너비창의 테두리를 포함한 전체 외부 너비**window.scrollX 속성**x축 scroll의 시작점 좌표**window.scrollY 속성**y축 scroll의 시작점 좌표**window.location 속성**현재 창의 URL을 나타내는 객체**window.history 속성**브라우저의 세션 기록을 조작하고 탐색할 수 있는 객체window.location.href vs window.history.push()일반적인 이동은 history.push(), 이동과 함께 새로고침이 필요한 경우는 window.location.href 추천공통점 : 페이지 이동 location.href history.push() HTTP 요청 수행 O X 새로고침 O X Applcation 상태 유지(ex. 리액트의 state) X O 용도 현재 페이지의 URL 제어 브라우저의 탐색 히스토리 조작**window.navigator 속성**브라우저의 정보와 기능을 제공하는 객체주로 브라우저의 종류, 버전, 운영 체제, 언어 설정 등을 확인하고, 이에 따라 웹 애플리케이션을 조건부로 실행하는 데 사용함웹 페이지 빌드 과정(CRP, Critical Rendering Path)HTML → DOM TreeCSS → CSSOM Tree1, 2렌더 엔진이 문서를 읽어들여 파싱어떤 내용을 페이지에 렌더링할 지 결정비용이 크지 않은 작업DOM Tree + CSSOM 결합 → Render Tree브라우저가 DOM과 CSSOM을 결합화면에 보이는 모든 콘텐츠와 스타일 정보를 모두 포함하는 최종 렌더링 트리 출력Layout(reflow)브라우저가 페이지에 표시되는 각 요소의 크기와 위치를 계산Paint실제 화면에 그리기 DOM노드 타입Element, Attribute(deprecated), Text node, Comment node, Document itself, Doctype모든 타입의 노드에 적용 가능한 탐색 프로퍼티parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling요소 노드(Element 타입)에만 적용 가능한 탐색 프로퍼티parentElement, children, firstElementChild, lastElementChild, previousElementSibling, nextElementSibling자식 노드바로 아래의 자식 요소후손 노드중첩 관계에 있는 모든 요소자식 노드와 그 아래 자식 노드 모두 포함**element.innerHTML**html까지 출력됨**element.innerText****innerText**는 해당 요소의 텍스트 콘텐츠만을 반환HTML 태그를 고려하여 렌더링된 텍스트를 반환함(공백을 하나로 처리)CSS로 display: none; 또는 **visibility: hidden;**으로 숨겨진 요소의 텍스트는 반환하지 않음**innerText**는 보다 시각적으로 화면에 나타나는 텍스트만을 반환하며, 렌더링된 결과를 고려하여 처리됨**element.textContent****textContent**는 해당 요소의 모든 텍스트 콘텐츠를 포함하여 모든 하위 요소의 텍스트도 포함하여 반환HTML 태그를 무시하고 텍스트만을 고려함. 즉, HTML 구조를 고려하지 않고 텍스트만을 처리HTML 태그의 텍스트도 그대로 반환되며, 스크립트에서 태그를 제거할 필요가 없음**textContent**는 보다 일반적인 텍스트 콘텐츠를 반환하며, 숨겨진 요소의 텍스트도 포함될 수 있음**element.childNodes**text 노드가 포함된 NodeList 반환text 노드 : line break(엔터, 한 칸 띄움) 포함하여 반환배열 같아 보이지만, 유사 배열 객체인 컬렉션 타입컬렉션 타입 특징배열에서 사용하는 메서드를 사용할 수 없음배열의 반복 for … of, forEach() 사용 가능 (for … in 불가능)**element.children**children element nodes 반환text 노드도 포함 DOM 제어parentNode.appendChild(node) : node 추가parentNode.removeChild(node) : node 삭제parentNode.replaceChild(newNode, oldNode) : oldNode를 newNode로 대체 Event Listener & Event 객체이벤트를 등록하는 방법자바스크립트 코드에서 프로퍼티로 등록 (ex. onload)HTML 태그에 속성으로 등록 (ex. onClick)addEventListener 메서드 활용element.addEventListener(이벤트명, 실행할 함수명, 옵션)Event 객체event.clientY : 브라우저로부터의 마우스 이벤트가 발생한 거리 Y 좌표event.offsetY : 요소로부터의 마우스 이벤트가 발생한 거리 Y 좌표event.target : 실제 이벤트가 시작된 타겟 요소this 또는 event.currentTarget : 핸들러가 할당된 요소 Event 종류UI 이벤트load문서나 객체가 로드 완료 되었을 때 발생change객체의 내용이 변동되거나 focus를 잃었을 때 발생resize객체의 크기가 바뀌었을 때 발생scroll스크롤바를 조작할 때 발생error에러가 발생했을 때 발생키보드 이벤트keydown키를 눌렀을 때 발생keyup키를 눌렀다 뗐을 때 발생keypress사용자가 누른 키의 문자가 입력되었을 때 발생마우스 이벤트click객체를 클릭했을 때 발생dblclick객체를 더블클릭했을 때 발생mousedown마우스를 클릭했을 때 발생mouseout 마우스가 요소 밖으로 나갔을 때 발생 (자식 요소에 대해서도 이벤트를 처리함)mouseleave마우스가 요소 밖으로 나갔을 때 발생 (자식 요소에 대해서는 이벤트를 처리하지 않음)mouseover 마우스가 요소 위로 올려졌을 때 발생mousemove마우스가 움직였을 때 발생mouseup마우스에서 손을 뗐을 때 발생포커스 이벤트focus객체에 focus가 되었을 때 발생blur객체가 focus를 잃었을 때 발생폼 이벤트inputinput, textarea 요소 값이 변경되었을 때 발생changeselect box, check box, radio button의 상태가 변경되었을 때 발생select텍스트를 선택했을 때 발생reset리셋 버튼을 눌렀을 때 발생submit사용자가 버튼키 등을 활용해 폼을 전송할 때 발생cut/copy/paste사용자가 폼 필드의 콘텐츠를 잘라내기/복사/붙여넣기했을 때 발생동일한 요소에 이벤트가 적용되어 있을 때, 이벤트 발생 순서keydown → keypress → keyupmousedown → mouseup → click이벤트의 3단계 흐름 캡처링 단계 : 이벤트가 하위 요소로 전파되는 단계타깃 단계 : 이벤트가 실제 타깃 요소에 전달되는 단계버블링 단계 : 이벤트가 상위 요소로 전파되는 단계 Event Bubbling이벤트 버블링이란, 가장 깊게 중첩된 요소에 이벤트가 발생했을 때 이벤트가 위로(bubble up) 전달 되는 것을 의미함타깃 이벤트에서 시작해서 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생3번 요소, 2번 요소, 1번 요소에 이벤트 핸들러가 있다면, 3번 요소 핸들러 → 2번 요소 핸들러 → 1번 요소 핸들러 순으로 실행됨event.stopPropagation() 메서드를 활용하여 버블링을 중단하면 부모 요소(상위 요소)의 핸들러는 호출되지 않음 Event Capturing이벤트 캡처링이란, 제일 상단에 있는 요소에서 아래로 이벤트가 내려오는 것을 의미함addEventListener() 메서드의 두 번째 인수에 { capture : true } 옵션을 넣어주면 캡처링 과정을 확인할 수 있음 이벤트 위임 (Event Delegation)하위 요소의 이벤트를 상위 요소에 위임하는 것을 의미. 즉, 하위 요소의 이벤트를 상위에서 제어함동일한 기능을 가진 요소임에도, 추후에 코드를 통해 추가된 요소일 경우 이벤트 리스너를 다시 등록해줘야 하는 번거로움이 있음 → 이벤트 위임을 활용하여 해결할 수 있음하지만 주의할 점이 한 가지 있음. 상위 요소에 등록된 이벤트 핸들러가 하위 요소에 있는 요소에 대해서만 동작하도록 설정해야함. 이렇게 하지 않으면 상위 요소의 아무 곳이나 클릭했을 때도 이벤트가 발생할 수 있음하위 요소가 버튼이라고 쳤을 때, 이벤트 핸들러에서 클릭된 요소가 버튼인지 확인하는 로직이 필요함  회고역시 기본기가 가장 중요하다는 것을 다시 느꼈다. React를 쓰며 state로 인해 자동으로 업데이트 되는 화면에 익숙해졌던 것 같다. 프레임워크와 라이브러리에 대한 의존 없이도 스스로 구현해낼 수 있도록 연습하는 것이 좋겠다.  

프론트엔드인프런워밍업스터디클럽FE1기발자국

짙은

[인프런 워밍업 스터디 클럽 1기] 백엔드 1주차 회고록

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]를 수강하고인프런 워밍업 클럽에 참여하여 쓰는 회고록입니다.   Plus 😍 정해진 진도표를 참고해 내 일정에 맞게 꾸준히 강의를 듣는건 오랜만인데 생각보다 더 좋다. 특히 강의의 구조가 그저 진도를 나가는데만 집중하는게 아니라 서론(문제 제기), 이론(제기된 문제의 해결), 결론(해당 개념이 나오게 된 이유와 어떻게 해결했는지에 대한 요약 정리)으로 이루어져 있어, 무턱대고 하루 n강을 수강하는 것보다 진도표를 참고해 유사한 내용을 하루 단위로 묶어서 들을 수 있어서 좋았다. 특히 이런 구조가 좋았던데는 개인적인 배경이 있는데...... 현재 나는 프론트엔드 개발자로 입사했으나, 회사의 방침(?)이 바뀌어 풀스택 개발자로 (반강제) 커리어 전환을 해야만 하는 환경에 있고, 백엔드 역량을 단시간내에 끌어올려야만 하는 상황이다. 이미 작성된 코드들을 참고해 CRUD를 (굉장히 천천히) 만들어낼수는 있지만, 왜 이런 구조로 나뉘어져 있는지는 코드를 통해서 알기 힘들었다. 다른 개발자들도 동일한 여건에 처해 있기 때문에 이런 구조에 대한 궁금증을 선뜻 물어보기가 쉽지 않은 환경인데, 강의에서 이런 부분들을 상세히 알려주어 도움이 많이 되었다. 특히 18강 Controller를 3단 분리하는 강의를 들으며 Layered Architecture에 대해 공부할 때 막연하게 '세 단계로 나누어서 코드를 작업하네'라고 생각했던 부분에 대해 명확한 이유를 알게 되어, 앞으로 백엔드 코드를 읽거나 작성할 때 도움이 많이 될 것 같다.   Minus 🥶 생각보다 내가 자바를 잘 모른다! 자바 책 또는 강의도 병행하면 좋겠지만, 사실 현재 진도표에 맞춰 강의를 듣는 것도 빡빡하다. 실습이 대부분이다보니 출퇴근 시간 지하철에서 강의를 듣는다거나 하는 식으로 병행하기 힘들다는 한계도 있다. 강의를 들으며 모르는 내용이 나올 때마다 검색으로 부족한 부분을 채워나가는 방식으로 (일단은) 메꾸어야 할 것 같다. 어떤 것들을 공부했었는지 키워드를 따로 정리했다가 백엔드 스터디가 종료되고 자바 기초 공부를 시작할 때 그 키워드들을 예의주시하며 공부하는게 최선일 것 같다. 회사의 개발 환경은 맥북인데, 집에서는 윈도우 PC를 이용하고 있다. 인텔리제이 키 매핑이 다르다보니 한번씩 혼란스럽다.   Interesting 🤔현재 DB에 적재된 데이터를 외부 팀의 요청에 맞게 추출하거나, 수정해야 할 때가 있는데 이런 요청과 쿼리를 정리해뒀다가 어드민 페이지에 추가 기능으로 구현하면 어떨까? 하는 생각이 들었다. 실제로 이전에도 반복되는 요청에 대해 추가 기능을 만들면 좋을 것 같다고 백엔드 개발자분께 건의한 적이 있지만 부정적인 답변을 받았었던 경험이 있다. 그렇지만 내가 프론트엔드부터 백엔드까지 모두 개발한다면 아무런 문제가 없지 않을까.   

백엔드인프런워밍업스터디클럽

노은빈

[인프런 워밍업 클럽 스터디] 1기 첫번째 발자국

발자국 남기기벌써 일주일이나 지나고 있다니 시간이 진짜 빠르다. 아무래도 신입을 많이 뽑지 않는 지금 시점에서 할 수 있는 건 공부뿐이라고 생각해서 미루고 미루다 자바 공부를 시작하며 스프링 공부를 해야겠다고 맘 먹었다. 근데 또 혼자하면 늘어지는 스타일이라 차라리 같이 공부하고 돈도 내고 해야 열심히 할 것 같아 스터디를 듣게 되었다..!! 근데 생각보다 내 일정이 빡빡해지는 바람에 1주차인 지금은 시간에 쫓기듯 공부하고 있지만 담주부터는 여유롭게 들을 수 있을 것 같다. 그럼 이제 1주간의 회고를 시작해보겠다!! Day0강의를 듣기에 앞서 OT를 온라인으로 진행했다. 앞으로 어떻게 진행되는지의 전반적인 부분을 말씀해주셨다.그리고 자바에 대한 짧은 특강을 해주셨다. 자바는 인터프리터? 컴파일 언어?프로그래밍 언어는 컴퓨터가 이해할 수 있는 언어로 번역해야한다 번역의 종류→ 통짜번역 ⇒ 컴파일러→ 그때그때 번역 ⇒ 인터프리터자바는 하이브리드 언어임(둘 다 가능) .Java → (compile) → .class → JVM컴파일도 하면서 한줄 한줄 읽음 시작부터 유용한 정보를 알려주셔서 넘 좋았다. tmi지만 최근에 정처기 실기를 공부해서 아는 내용이라 공부를 안 하고 있는 건 아니구나 라는 안심을 조금 했다😅 Section0강의를 시작하기 전의 섹션 0 에서는 강의 시작 전 준비와 수업 자료에 대한 내용이었다.대부분의 내용은 이미 알고 있던 거고 다 다운받아져 있던 거라 설명만 조금 들었다.지금 내 노트북은 맥북 m2인데 사실 그냥 homebrew로 다운 받으면 버전이 안 맞거나 잘못 받아서 경로가 이상해지는 현상이 많이 발생한다.이전에 MySQL을 설치하면서 많은 충돌이 있어서 나중에 잊지 않으려고 블로그와 노션에 열심히 정리해두었다.https://velog.io/@dmsqls19/ERROR-mac에서-MySQL-완전-삭제-후-재설치-오류Homebrew-사용했을-경우나중에 같은 오류가 있다면 이 글을 보고 있는 분도 잘 해결했으면 좋겠다! Section1섹션 1부터는 본격적인 강의 시작이다.자바를 공부하기 전에 알아두면 좋은 강의 2개를 올려주셨는데 정말 유익한 내용이다.첫번째 강의에서는 Java라는 언어를 컴퓨터가 알게 되기까지의 과정이 나오는데 컴파일을 통해 사람의 언어를 컴퓨터가 인식하게 된다고 한다. 자바는 다른 언어와 다르게 컴파일러 하나로 모든 운영체제에 사용할 수 있다.JDK > JRE > JVM 라서 JDK를 설치하면 JRE와 JVM도 함께 설치된다.JDK의 버전과 종류는 다양한데 LTS라는 안정화된 버전을 사용하는 것이 좋다.두번째 강의에서는 빌드와 실행에 대해 배우는데 빌드란 소스 코드 파일을 컴퓨터에서 실행할 수 있는 독립 SW 가공물로 변환시키는 과정이다. 테스트 코드도 빌드 과정의 일부인데 테스트 코드를 작성해서 개발 속도 및 안정성의 품질을 높여주는 것이 좋다. 그 다음 오픈 소스와 우리가 만든 코드를 합치는 과정을 패키징이라 하는데 패키징을 하면 빌드 과정의 끝이다. 실행(Run)을 해서 내가 작성한 코드를 작동시킬 수 있는데 Artifact가 나올 수도 있고 나오지 않을 수도 있다는 점에서 빌드와 차이점이 있다. 빌드는 수동으로 하게 되면 실수가 많이 나올 수 있으므로 빌드 툴을 이용하는 것이 좋은데 요즘 가장 많이 쓰이는 빌드 툴은 maven과 gradle이다.이제 본격적으로 강의를 시작하는데 처음에는 스프링 프로젝트를 시작하는 방법에 대해 배운다. 그 다음 @SpringBootApplication 에 대해 배우면서 어노테이션이 무엇이고 서버란 무엇인지에 대해 배운다.첫번째 과제가 바로 어노테이션에 관한 과제였다. 스스로 찾아보면서 공부를 하니 이해가 더 잘 되는 것 같기도 하면서 아리송하기도 하다. 📄과제1. 어노테이션 그 후 네트워크와 HTTP, API에 대한 것을 배우는데 백엔드를 공부하는 사람에게 필요한 내용을 배워서 좋은 강의라고 느끼는 부분이았다.api에 대해 배운 후 get과 post를 직접 해보는데 처음에는 더하기, 곱하기를 해보며 postman도 써보고 코드도 직접 작성해봤다. 그 다음에 유저 정보 조회를 하는 get api와 유저 정보를 저장하는 post api에 대해 배웠다. 미리 get과 post를 해보고 하니 더욱 쉽게 느껴졌다. 두번째 과제는 get api와 post api를 직접 연습하는 과제였는데 자바에 좀 덜 익숙해서 그런지 좀 어려운 과제였다. 그래도 두 번 보니 처음 과제를 마주했을 때보단 쉬웠다.📄과제2. GET API, POST API Section2섹션2에서는 서버와 데이터베이스를 연결하는 과정이다. 데이터베이스는 MySQL을 사용했다. 데이터베이스가 서버에 필요한 이유는 메모리에서만 유지되는 유저 정보를 서버단에 올리기 위해서 필요하다. 강사님이 서버에 올리는 두 가지 방법을 알려주셨는데 하나는 인텔리제이 유료 버전으로 인텔리제이에서 하는 방법과 터미널에서 MySQL을 사용하는 방법이었다. 나는 인텔리제이에서 하는게 더 편한 것 같아 첫번째 방법을 사용했다.데이터베이스에 대해 공부하고 sql 문법에 대해 배운다. 나는 최근에 정처기 시험 때문에 이미 너무 많이 봐서 어렵게 느껴지진 않았다. 그 후 스프링과 데이터베이스를 연결하는 과정을 배우는데 코드 따라치는 건 어렵지 않은데 자바가 익숙한 건 아니라서 이해를 하는데 조금 오래 걸렸다. 그래도 오래 보다보면 또 이해가 되기 때문에 조금 더 많은 시간을 들여 공부를 해야겠다고 생각했다.연결 후에는 유저 업데이트와 삭제를 해보면서 정말 db에 유저 정보가 들어가는지 확인했다. 그 다음 유저 정보가 없을 경우에 업데이트, 삭제가 되는 예외처리를 해주었다.그리고 과제로는 sql을 연결해보며 나온 람다식에 대해 조사하는 과제였다. 찾아보면서 이해 못한 부분을 조금 더 이해하게 되었다.📄과제3. 익명 클래스와 암다식 5일차에는 중간점검이 한 번 있었는데 질문하는 것을 답변해주는 시간이었다.나도 신입 개발자로서 궁금했던 점들을 다른 분들이 많이 질문해주셔서 답변을 들으며 엄청 유익해서 뭔가 이런 시간이 조금 더 많으면 좋겠다는 생각이 들었다.이번주는 시간이 조금 빠듯해서 진도표보다 조금 덜 공부했다. 다음주는 시간이 많아서 아마 더 할 수 있을 것 같다. 한 주 동안 공부해보면서 아직 자바 공부가 많이 부족하다는 걸 깨달았다. 그래서 다음주는 자바 공부를 하면서 강의를 들을 예정이다. 공부하면서 회고도 하고 과제도 하니 진짜 같이 공부하는 기분이 들어 더 열심히 해야겠다고 다짐했다!! 📚공부했던 내용 정리 노션 https://quartz-mastodon-ac1.notion.site/6ae20b419ca9400c94b4df9ab8f2f3da?pvs=4 

백엔드인프런워밍업클럽1기BE

한지은

[인프런 워밍업 스터디 클럽 1기] FE 1주차 발자국

day2 - 1번 과제https://github.com/jjajan2/inflearn_study/tree/main/day2_food_menu따라하며 배우는 자바스크립트 A-Z 강의 섹션 1~3까지 듣고, 과제가 있었다!간단하게 메뉴탭을 제작하는 과제였다. 탭을 클릭했을때, 해당 카테고리에 맞는 메뉴를 보여주는 과제였다. 별다른 기능이 없기에 가독성이 좋은 코드를 만들고 싶어서 템플릿 리터럴을 사용해 코드를 작성했다. 과제를 완료하고나서, 다른분들은 어떻게 했을지 궁금해서 다른분의 코드를 확인해보니, createElement와 appendChild 를 사용해서 작성하시는 분들이 많았다.그래서 두가지 방식의 차이를 찾아보았다.createElement()생성된 요소에 이벤트 리스너를 추가하거나 스타일을 적용하기 쉽다.코드의 가독성과 유지보수성이 좋다.브라우저 지원 97.92%템플릿 리터럴코드가 간결하고 읽기 쉽다.생성된 HTML 요소에 이벤트 리스너를 추가하거나 스타일을 적용하려면 별도의 작업이 필요브라우저 지원97.11%Opera 및 blackberry에서 지원하지 않음💡 결론 : 두 방식 모두 큰 차이가 없기 때문에 프로젝트의 요구사항과 개발자의 선호도에 따라 선택할 수 있다.참고 링크 : https://levelup.gitconnected.com/javascript-createelement-vs-template-literals-baa50ec2e941 day3 - 2번 과제https://github.com/jjajan2/inflearn_study/tree/main/day3_rock_paper_scissors처음에는 이미지를 넣지않고 만들었지만, 사용자가 보기에 불편하다는 느낌이 있어서 이미지를 삽입했다! day4 - 3번 과제https://github.com/jjajan2/inflearn_study/tree/main/day4_quiz오늘은 퀴즈 앱을 만드는 과제가 있었다. 가위바위보 앱과 흐름은 어느정도 비슷해서 어렵지 않았지만, 정답이 정해져있어서 생기는 궁금증이 있었다. 내가 처음에 작성한 question.json 파일의 경우 { "question": "자바스크립트에서 변수 또는 상수를 선언하는 키워드가 아닌 것은?", "option": ["const", "let", "init", "var"], "correct": "init" }, 이런 형태의 구조였는데, 코드를 작성하다보니 correct 에 정답의 index를 적어두어도 되겠다는 생각을 했다. 하지만 option 배열의 구조가 변경될 경우 correct의 값도 변경해주어야하니 번거로움이 생길까 하는 우려가 생겼다.정답을 적어두는 방식은 가독성이 편리하고, 코드 작성, 관리 하기에는 index를 적어두는 것이 편하겠다는 생각이 들었다. 하지만 가장 처음에 작성해둔 가독성이 좋은 방식으로 진행하기로 했다!그리고 코드를 거의 다 작성하고나서, 문제를 풀고 다음버튼을 누르기 전에 문제 버튼을 다시 누르면 아이콘들이 계속해서 추가되는 문제를 발견했다.그래서 버튼을 클릭 하고 다음으로 넘어가기전 버튼을 disabled 하는 방식으로 해결했다! day5 - 4번 과제https://github.com/jjajan2/inflearn_study/tree/main/day5_book_list이번 과제를 하면서 로컬호스트에 공부할 수 있어서 좋았다! 처음에는 책 자체를 로컬호스트에 바로 저장하고,로컬호스트 값을 전부 가져오는 방식으로 만들었는데, 이럴경우 다른 웹페이지에서 저장된 로컬호스트 데이터까지 가져오게 되는 문제가 생겨서 book_list로 키를 지정하고, 배열에 저장하는 방식으로 변경했다!완료하고나니까 간단한 문제였는데 바로 생각하지 못했던게 아쉽다. day5 - 5번 과제https://github.com/jjajan2/inflearn_study/tree/main/day5_github_finder처음에 Octokit.js 를 사용하는 방식으로 만들었다가, 굳이 그럴필요없이 axios나 fetch를 사용하는 방식으로 변경했다!여태 axios만 사용해봤는데 fetch를 사용하는 방법도 axios와 크게 다르지 않아서 금방 적응할 수 있었다. 1주차 과제들은 Section 1 ~ 3 에서 배운 개념을 지루하지 않은 토이프로젝트로 직접 사용할 수 있어서 좋았다.그냥 강의를 다시 듣거나 기록만 하는것보다 더 복습이 잘 되는 느낌이었다. 확실히 강의만 듣는거랑 실제로 코드를 쳐보는것은 확실한 차이가 있었다. 처음에 큰 덩어리로 과제를 봤을때는 어디서 부터 시작해야될지 막막했는데, 큰 덩어리를 작게 나눠서 차근차근 작성하니까 생각보다는 금방 할 수 있었다!1주차는 강의 보다는 과제에 집중했던 느낌이라서 아쉽다. 2주차에는 강의도 성실하게 잘 들어야겠다는 생각이 든다.기초가 탄탄해야 사소한 실수를 하지 않는 것 같다. 2주차에는 1주차 강의도 틈틈이 복습해봐야겠다.

프론트엔드워밍업클럽FE1기

seong2808

[인프런 워밍업 스터디 클럽 1기] 첫 번째 발자국

발자국강의는 진도표에 맞춰 진행하였으며 회고록 또한 그에 맞춰 작성하였다.인프런 워밍업 스터디 클럽 완주를 목표로 남은 기간동안 매일매일 꾸준히 학습하기 위해 노력하겠다.1주차 학습 내용DAY 1 : 서버개발을 위한 환경 설정 및 네트워크 기초1강 : 스프링 프로젝트를 시작하는 두번째 방법스프링 프로젝트를 시작하는 방법은 크게 2가지가 있다.이미 만들어져 있는 프로젝트를 다운하거나 Spring initializr ( https://start.spring.io/ )를 이용해 새로운 프로젝트를 시작한다.위의 이미지와 같은 홈페이지에 접속하여 프로젝트의 빌드툴, 이름, 서버개발에 사용할 언어, 의존성을 설정하여 시작할 수 있다. 2강 : @SpringBootApplication과 서버@SpringBootApplication 어노테이션 : 스프링을 실행시키기 위한 다양한 설정을 자동으로 처리해 준다.server : 어떠한 기능을 제공하는 프로그램, 프로그램을 실행시키고 있는 컴퓨터를 의미한다. 3강 : 네트워크란 무엇인가?IP : 컴퓨터별 고유 주소port : 여러 프로그램 중 하나만을 특정하는 것을 의미Domain Name : 244.65.51.9 대신 spring.com 으로 표현이러한 체계를 Domain Name System (DNS) 라고 한다. 4강 : HTTP와 API란 무엇인가?HTTP (HyperText Transfer Protocol) : 데이터를 주고 받는 표준Protocol : 표준, 약속GET / portion?color=red&count=2 HOST:spring.com:3000GET : 요청 행위 → HTTP MethodHOST : 요청을 받는 컴퓨터와 프로그램 정보/portion : Path, HTTP 요청을 받는 컴퓨터에게 원하는 자원? & : 구분 기호?color=red&count=2 -> 원하는 조건, Query라고 부른다.각 HTTP Method 마다 사용되는 것이 다르다.GET : Query 사용 (조회)POST : Body 사용 (생성) PUT : Body 사용 (수정) DELETE : Query 사용 (삭제)API (Application Programming Interface) : 정해진 약속을 하여 특정 기능을 수행하는 것URL (Uniform Resource Locator) : 주소창 (ex. http://spring.com:3000/porting?color=red&count=2) 5강 : GET API 개발하고 테스트하기API를 개발하기에 앞서 API를 이루고 있는 요소들을 설계해야한다. 이를 API Specification (명세) 라고 한다.Controller, DTO 생성과 GET API 작성 이후 만들어진 API를 Postman으로 테스트하는 실습을 진행하였다. DAY 2 : 첫 HTTP API 개발6강. POST API 개발하고 테스트하기Controller, DTO 생성과 POST API 작성 이후 만들어진 API를 Postman으로 테스트하는 실습을 진행하였다.데이터를 어떻게 받을까? → HTTP BODY를 통해 받는다.BODY로 데이터를 어떻게 받을까? -> JSONJSON : 객체 표기법, Map<Object, Object> 느낌{ "name": "강성관", "age": 26 }JSON의 value에는 리스트, 객체 등등 다양한 타입을 받을 수 있다.@RequestBody : HTTP Body로 들어오는 JSON을 주어진 객체로 변경해주는 어노테이션@PostMapping("/multiply") public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) { return request.getNumber1() * request.getNumber2(); }즉, HTTP Body는 CalculatorMultiplyRequest에 매핑된다. 7강. 유저 생성 API 개발도서관 애플리케이션의 요구사항사용자사용자 등록사용자 목록 조회사용자 이름 업데이트사용자 삭제책책 등록 및 삭제사용자 책 대여다른 사람이 그 책을 빌렸다면 빌릴 수 없다책 반납API 설계Method : POSTpath : /userBody (JSON){ "name": String (null 불가능) "age": Integer } 결과 반환 X (HTTP 상태 200 OK이면 충분하다)  8강. 유저 조회 API 개발과 테스트결과 반환이 JSON이다? Controller 에서 getter가 있는 객체를 반환하면 JSON이 된다.Id는 무엇인가?유저별로 겹치지 않는 유일한 번호List에 담겨 있는 유저의 순서를 id로 정하여 진행 DAY 3 : 기본적인 데이터베이스 사용법10강. Database와 MySQLDatebase와 Mysql의 사전 지식과 연결 방법에 대한 설명11강. MySQL에서 테이블 만들기//데이터베이스 만들기 create database 데이터베이스명; //데이터베이스 목록 보기 show databases; //데이터베이스 지우기 drop database 데이터베이스명; //데이터베이스 안으로 들어가기 use 데이터베이스명; //테이블 목록 보기 show tables; //테이블 만들기 create table 테이블명 ( 필드명 타입 부가조건 필드명 타입 부가조건 ... primary key (필드이름) ); MySQL 타입 살펴보기정수 타입tinyint : 1 바이트 정수int : 4 바이트 정수bigint : 8 바이트 정수실수 타입double : 8 바이트 정수decimal(A, B) : 소수점을 B개 가지고 있는 전체 A자릿수 실수 ex) Decimal(4, 2) = 12.23문자열 타입char(A) : A글자가 들어갈 수 있는 문자열varchar(A): 최대 A글자가 들어갈 수 있는 문자열날짜, 시간 타입date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss12강. 테이블의 데이터를 조작하기//데이터 넣기 INSERT INTO 테이블명 (필트명, 필트명, ...) VALUES (값, 값, ...); //데이터 조회 (* 대신 필드명을 넣을 수 있다.) SELETE * FROM 테이블명; //데이터 조회 필터 사용 (AND와 OR를 통해 이어붙일 수 있다.) SELETE * FROM 테이블명 WHERE 조건; //데이터 업데이트하기 (조건을 붙이지 않는다면 모든 데이터가 수정된다.) UPDATE 테이블명 SET 필드명 = 값, 필드명 = 값 WHERE 조건; //데이터 삭제 (조건을 붙이지 않는다면 모든 데이터가 삭제된다.) DELETE FROM 테이블명 WHERE 조건; 13강. Spring 에서 Database 사용하기스프일 서버가 MySQL DB에 접근하는 방법application.yml 만들고 설정하기spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driver 이후, User 테이블 생성 후 기존의 실습을 진행하면서 메모리에 저장하던 유저정보를 MySQL에 저장하게 바꾸는 실습을 진행하였다. DAY 4 : 데이터베이스를 사용해 만드는 API14강. 유저 업데이트 API. 삭제 API 개발과 테스트도서관 사용자 이름 업데이트HTTP Method : PUTHTTP Path : /userHTTP Body (JSON){ "id": Long, "name": String // 변경되어야 하는 이름이 들어온다. } 결과 반환 X (HTTP 상태 200 OK이면 충분)사용자 삭제HTTP Method : DELETEHTTP Path : /user쿼리 사용문자열 name결관 반환 X한가지 문제 발생 → 수정과 삭제할 때 데이터베이스에 없는 유저를 수정하거나 삭제 시 200 OK를 반환15강. 유저 업데이트, 삭제 API 예외 처리 하기데이터 존재 여부 확인 후 예외를 던지자!실습 진행!@PutMapping("/user") public void updateUser(@RequestBody UserUpdateRequest request) { // 해당 id를 가지고 있는 User가 있는지 확인하는 쿼리 String readSql = "SELECT * FROM user WHERE id = ?"; // 있다면 0를 가지고 있는 List 생성, 아니면 빈 List 생성, // .isEmpty()를 이용하여 비어있다면 True 아니면 false 반환 boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty(); if (isUserNotExist) { throw new IllegalArgumentException(); } String sql = "UPDATE user SET name = ? WHERE id = ?"; jdbcTemplate.update(sql, request.getName(), request.getId()); } @DeleteMapping("/user") public void deleteUser(@RequestParam String name) { // 해당 name를 가지고 있는 User가 있는지 확인하는 쿼리 String readSql = "SELECT * FROM user WHERE name = ?"; // 있다면 0를 가지고 있는 List 생성, 아니면 빈 List 생성, // .isEmpty()를 이용하여 비어있다면 True 아니면 false 반환 boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, name).isEmpty(); if (isUserNotExist) throw new IllegalArgumentException(); String sql = "DELETE FROM user WHERE name = ?"; jdbcTemplate.update(sql, name); }  DAY 5 : 클린코드의 개념과 첫 리펙토링17강. 좋은 코드는 왜 중요한가?Code는 요구사항을 표현하는 언어이고 개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다.하지만 다른 사람이 작성하는 코드와 내가 예전에 작성해둔 코드를 다시 읽었을 때, 다시 이해하는 것은 쉬운 일이 아니다.개발자에게 코드를 읽고 이해하는 것은 필수적이고 피할 수 없다.그럼 코드를 봤을 때, 무엇을 하는지 알 수 없는 코드를 이해하려는 것과 어떤 동작을 하고 무엇을 원하는지 의미를 파악할 수 있는 코드를 이해하는 것은 차이가 크다는 것을 알 수 있다. 18강. Controller 3단 분리하기기존의 Controller에 하나로 뭉쳐있는 코드를 Service와 repository로 나누는 리팩토링 과정의 실습을 진행하였다.Controller와1주차 과제과제 1질문 1. 어노테이션을 사용하는 이유 (효과) 는 무엇일까?질문 2. 나만의 어노테이션을 어떻게 만들 수 있을까? 평소 공부하면서 어노테이션을 사용하는 이유에 대해 명확하게 알지 못했다. 과제를 통해 어노테이션의 사용 이유와 효과, 각각의 기능이 어떻게 동작하는지 알 수 있었다. 특히, 롬복을 통해 getter, setter, 생성자를 자동으로 생성하고 주입하는 기능을 알 수 있었다. 나만의 어노테이션을 만들 때, @Retention 어노테이션을 사용하여 나만의 어노테이션을 정의하고 유지한다는 것을 알게 되었다. 과제 2 API 명세를 통해 GET, POST API 만들기 자신있게 시작했던 모습은 얼마 가지 않아 헤매는 부분이 있었던 것 같다. 총 3문제 중 첫문제만 Request 파일과 Response 파일을 만들 수 있었다. 시간에 쫓겨 못한 부분이 있었다. 다음에는 시간을 가지고 좀 더 많은 고민을 하면서 완성하고 싶다. 과제 3질문 1. 자바의 람다식은 왜 등장했을까?질문 2. 람다식과 익명 클래스는 어떤 관계가 있을까? 람다 도입 배경이 다른 언어에 뒤쳐지지 않고 큰 데이터를 다루기 위해 병렬성 활용과 간결한 코드의 중요성이 올라 갔기 때문이다.알지 못하고 사용했던 때보다 람다의 도입 배경을 알고 적절한 곳에 사용할 수 있을 것 같다. 람다식과 익명 클래스의 관계를 알아보며 람다는 사실 익명 클래스의 객체라는 점이 놀라웠다. 

백엔드인프런워밍업스터디클럽발자국

이삭토스트

[인프런 워밍업 클럽 스터디1기] BE 1주차 회고록

 강의 수강 1일차 - 서버 개발을 위한 기본 환경 설정 및 네트워크 기초 기본적인 내용을 배우는 시간, HTTP 네트워크 기초에 대해서 배우고 있는 내용이 있어서 기본에 배웠던 내용들을 복습하는 시간이 되었다.2일차 - 첫 HTTP API 개발 대표적으로 GET과 POST를 나타내며 데이터를 전달하는 방법이 쿼리와 Body(JSON)으로 나뉘며 자세하게 모르고 있었던 JSON을 받는 방법에 대해서 알게 되었다.예전에 배웠던 부트캠프에서 스프링을 배우다가 dto 개념을 제대로 모르는 상태에서 프로젝트에 투입이 되었는데, request 와 response 을 활용하지 못하여 주어진 소스코드를 이해하지 못해서 구조를 어떻게 활용을 해야하나 고민했었다.그리고 다양한 파라미터와 JSON을 받아서 어떻게 컨트롤러 단에서 처리를 해야하는지 전혀 감이 잡히지 않았는데 최태현 코치님이 보여주신 구체적인 예를 통해서 막연한 안개가 걷힌 느낌이 들었다.  3일차 - 기본적인 데이터베이스 사용법 MySQL에 대해서 이론적인 부분은 배운 상태이지만 우리가 실무적인 면에서 주로 사용하는 명령어들을 통해서 MySQL을 어떻게 사용해야 할지 감을 잡게 되었다.JPA를 이론적으로는 알고 있는 상황이지만 실질적인 프로젝트에 적용해본 상태는 아니다. JPA를 JdbcTemplate대신에 사용한다는 것을 알지만, 어떤 범위에 사용하는지를 몰랐고 그 기본적인 사용법을 알고나서 이후에 있는 JPA를 어떻게 적용할지 조금 두근거리긴한다.무엇보다 백엔드는 어떤 역할을 하는지(기능, 로직, DB...) 구체적으로 체험 할 수 있게 되었다.4일차 - 데이터베이스를 만드는 API 구체적으로 jdbcTemplate를 사용하는 구간이 아닌가 싶다. DB를 사용하면서, 데이터 자체가 유효한 값을 가지는지, 정당한 요청이 오지 않아 오류를 던져준다던지(예외 처리) 확인하는 구간이다.5일차 - 클린코드의 개념과 첫 리팩토링 클린코드에 대해서 많이 들었던 기억이 있다. 이론적으로만 들었기에 어떻게 적용할지 몰랐는데, Controller에 너무 많은 역할이 존재하므로 Controller - HTTP 관련 역할 담당 , Service - 분기처리, 로직 담당, Repository - DB와 접근을 담당으로 나눈 방법을 통해서 클린코드를 구체적인 방법으로 체험하는 시간이었다. 미션1일차 - 자바 어노테이션 스프링에서 현업에 사용하시는 분들의 필요에 의해서 이미 여러개의 어노테이션이 정립이 되어있는 것으로 기억한다. 하지만 그게 어떤 원리로 작성이 되었는지는 모르고 있다. 특히 원초적인 자바 어노테이션은 더더욱 알일이 없다. 일반적인 어노테이션은 눈에 익을 만큼 자주 보이지만, 일반적인 어노테이션에서 벗어나는 특별한 어노테이션이 필요할 때는 커스텀 어노테이션을 작성한다는 것을 알게 되었다. 특히 커스텀 어노테이션을 만들어 반복작업을 줄이는 노력을 할 수 있다는 것이다.다양한 답변들을 알아보기 위해서 네이버, 구글, ChatGPT를 사용하여 여러 방면으로 데이터를 얻고자 했고, 이론적인 부분만 존재하는 것보다는 최대한 개발자에게 있어 최고의 문서인 코드를 통해서 나타내는 예시들을 골라서 정리했다.2일차 - 추가적인 API 개발 쿼리 파라미터를 받아서 JSON으로 반환하는 방법을 배우고, LocalDate를 이용하여 날짜를 받아서 getDayOfWeek()을 이용하여 날짜를 나타내는 방법을 배웠다.마지막으로는 쿼리 파라미터가 아니라 JSON 바디로 받으면서 또 List를 가지고 있는 JSON을 이용하여 API를 만드는 방법에 대해서도 배우게 되었다. 힌트로 알려 주신게 컸지만 DTO에서 List를 받아 iter로 반복하여 API가 기능하게끔 반환 할 수 있다. POST MAN의 API 테스트 툴이 정말 절실하다는 것을 느끼게 되었다.3일차 - 익명 클래스와 람다식 람다식은 함수형 프로그래밍 개념을 자바에 도입하기 위해서, 코드를 더 간결하고, 읽게 쉽게 만들고, 성능이 중요시 되는 최근 병렬 처리와 이벤트 기반 프로그래밍으로 효율적으로 대응 할 수 있다.람다식과 익명 클래스의 관계는람다식은 익명 함수를 간결하게 표기, 익명 클래스는 이름이 없는 클래스 = 주로 인터페이스 구현체 생성에 사용한다.그러므로 람다식은 익명 클래스를 대체, 코드가 더 간결해지고 가독성이 향상 된다.함수형 프로그래밍, 익명클래스, 람다식, 함수형 인터페이스, 스트림 API, 메소드 레퍼런스등 저 2개의 질문에 대해서 많은 양의 검색과 정리를 통해서 답을 도출해낼 수 있었다. 도입배경과 적용 방법 등이 있지만 무엇보다 많은 숙련도를 요구하는 방법이다보니 쉽게 접근하지 못하지만 분명 열심히 단련하면 좋은 접근 방식인 것 같다. 4일차 - 추가적인 API 개발기존 API 개발에서 발전하여 JdbcTemplate를 적용하여 API를 작성하는 과제였다.다만 단순하게 API를 작성한다면 각각의 요구에 맞게 작성을 해나가면 되겠지만, 이번 과제는 모든 요구사항을 확인하여 테이블을 작성하고나서 문제를 해결해나가는 것이 도움이 되었던 것 같다. 마치 Q&A에서 기획 -> 논의 -> 개발 단계처럼 먼저 기획을 통해서 기능을 적고, 이후 API 명세서를 만들고 DB 스키마를 만들고나서, 개발 단계로 들어가 직접 코드를 타이핑 하는 과정 처럼 말이다. 5일차 - 클린 코드과제로 주어진 코드를 코딩테스트를 준비하던 과정에서 겪었던 것 처럼, 입력을 받고 기본적인 설정을 하는 구간 / 주사위를 굴리고 카운트 하는 클래스 / 주사위가 나온 횟수를 출력하는 클래스 등으로 나눠서 명확하게 나누어 읽기 쉬운 코드를 만드는게 클린 코드를 만드는 방법일 것 같다.사실 이런 과정이 어렵지는 않았는데 코딩테스트 스터디를 준비하면서 여러 언어가 모이게 되고소통의 어려움이 있었다. 좀 더 구성을 깔끔하게 나누어 클래스로 구성하고 주석을 통해서 어떤 기능을 하는지 알려주어 소통의 어려움을 해결 했던 경험이 한 몫을 했던 것 같다.  

백엔드워밍업스터디BE1기회고록

역직렬화

[인프런 워밍업 스터디1기] 3일차 진도표

1.자바의 람다식은 왜 등장했을까?람다식에 대해 꼭 알아야 할 JAVA8과 람다의 영어원문이다 https://www.oracle.com/technical-resources/articles/java/architect-lambdas-part1.htmlJava 8에는 이러한 코드 블록을 더 쉽게 작성할 수 있도록 설계된 몇 가지 새로운 언어 기능이 도입되었습니다. 핵심 기능은 람다 표현식 (구어적으로 클로저 (이유는 나중에 논의할 예정임) 이라고도 함 ) 또는 익명 메서드 입니다 .[해당오라클 원문 발췌]Lambda expressions. Funda-men-tally, a lambda expression is just a shorter way of writing an implementation of a method for later execution. Thus, while we used to define a Runnable as shown in Listing 2, which uses the anonymous inner class syntax and clearly suffers from a “vertical problem” 람다식의 도입으로 인해, 자바는 객체지향언어인 동시에 함수형 언어가 되는 계기가 되었다! 람다식 의미와 문법특징1. 메서드와 달리 이름이 없다.2. 메서드와 달리 특정 클래스에 종속되지 않지만, 매개변수, 반환 타입, 본체를 가지며, 심지어 예외도 처리할 수 있다.3. 메서드의 인수로 전달될 수도 있고 변수에 대입될 수 있다.4. 익명 구현 객체와 달리 메서드의 핵심 부분만 포함한다.람다식의 규칙선언부의 타입은 추론할 수 있으므로 타입을 생략해도 된다.매개변수가 하나 있다면 괄호를 생략해도 된다.실행문이 하나 있다면 중괄호와 세미콜론을 생략할 수 있다. 단, 실행문이 하나의 return문이면 return 키워드도 생략해야 한다.Arrays.sort(strs, new Comparator <String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2) * -1; } }); System.out.prinln(Arrays.toString(strs)); 람다식을 사용하여 간결한 코드로 작성한 예제Arrays.sort(strs, (o1, o2) -> {return o1.compareTo(o2) * -1 }); System.out.println(Arrays.toString(strs));너무 간단해진 람다식 사용으로 인한 코드의 간결성!즉, 함수를 값으로 전달하는데, 어딘가에 구현하지 않고 그냥 간단하게 구현해서 넘기고 싶으면 람다식을 이용람다식은 “함수 값”으로 평가되며, 한 번만 사용된다. 2.람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?위에 오라클 공식문서에도 나오지만 익명클래스의 긴코드를 람다식으로 간결하게 사용가능하며 여기서 함수형 인터페이스 개념도 알아두어야 한다!즉, 함수형 인터페이스의 특성으로 인해 익명클래스, 익명메소드의 뻔한 부분을 생략시킬 수 있게되고, 최종적으로 생략한 형태를 람다표현식이라고 부르게 되는 것이다. 함수형 인터페이스자바에서 모든 메서드는 클래스 내에 포함되어야 하는데, 람다식은 어떤 클래스냐고 진위를 묻는다면 지금까지 람다식이 메서드와 동등한 것처럼 설명해왔지만, 사실 람다식은 익명 클래스의 객체와 동등하다. 참조변수가 있어야 객체의 메서드를 호출 할 수 있으니까 일단 이 익명 객체의 주소를 f라는 참조변수에 저장해 보자.타입 f = (int a, int b) -> a > b ? a : b; //참조 변수의 타입은 뭐로 해야할까?참조형이기 때문에 클래스 또는 인터페이스가 가능하다. 람다식과 동등한 메서드가 정의되어 있어야함그래야만 참조변수로 익명 객체(람다식)의 메서드를 호출 예를 들어 아래와 같이 max()라는 메서드가 정의된 MyFunction 인터페이스가 정의되어 있다고 가정하자.interface MyFunction() { public abstract int max(int a, int b);그러면 이 인터페이스를 구현한 익명 클래스의 객체의 예MyFunction f = new MyFunction() { public int max(int a, int b) { return a > b ? a : b; } }; int big = f.max(5, 3); //익명 객체의 메서드를 호출가장 중요!결국 코드를 깔끔하게 작성하기 위해 함수형 인터페이스가 필요했고, 함수형 인터페이스의 특성으로 인해 익명클래스와 익명메소드의 뻔한 코드를 삭제하고 람다표현식으로 깔끔하게 표현

백엔드백엔드

코파

인프런 워밍업 클럽 1기 FE 6번 과제 (비밀번호 생성 앱)

6번 과제 (Day6)(비밀번호 생성 앱)깃허브 저장소 주소 :https://github.com/devellybutton/frontEnd_warmingUp_study/tree/master/06.%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8%EC%83%9D%EC%84%B1 과제 GIF:클릭한 종류의 문자열이 적어도 1개 이상 들어가도록 함. 모든 체크를 해제하고 'Generate'를 누르면 생성된 비밀번호가 초기화됨. 간단한 후기 :프론트엔드를 제대로 해본 적이 없어서 브라우저에서 클립보드를 조작하는 것을 처음 해보았습니다.구글 폰트 외에도 google material icon도 사용 가능하다는 것을 알게 되었습니다.이 정도 기능의 어플은 HTML 만들고 JS로 조작하는 것까지는 오래 걸리지 않지만, CSS까지 적용하니까 시간이 오래걸렸습니다. 항상 CSS가 문제인 것 같습니다.자바스크립트를 조작할 때는 각 옵션마다 적어도 1개 이상의 문자열이 랜덤으로 들어가야 하는 조건을 구현하는 것이 조금 까다로웠습니다. 처음에는 단순히 체크한 옵션의 문자열을 더해서 인덱스를 랜덤으로 생성되게 하였습니다. 하지만 그렇게 되면 선택한 옵션의 문자열이 들어가지 않는 경우가 발생해서(ex. 네 가지 다 선택하였음에도 Capital Letter는 하나도 들어가지 않은 경우) 로직을 변경하였습니다. 이미지 출처 :https://www.freepik.com/free-vector/padlock-security-safeguard-with-code-key-vector-locked-padlock-privacy-protect-tool-close-box-with-password-combination-system-lock-secure-equipment-template-realistic-3d-illustration_25191429.htm#query=lock%20png&position=7&from_view=keyword&track=ais&uuid=3024a5a2-6d85-4602-9058-ffaa8c44ee1dhttps://www.vecteezy.com/vector-art/23509276-gold-and-black-colors-bricks-wall-background-abstract-line-geometric-backdrop-minimal-design-style-stone-wall-texture-background-futuristic-art개발할 때 참고한 링크 :https://wooooooak.github.io/css%20challenge/2019/02/03/css_challenge_2/

웹 개발워밍업클럽FE과제

eus247

인프런 워밍업 클럽 스터디 1기 FE - 1주차 발자국

 강의 정리노션 링크로 대체합니다.https://synonymous-currant-9b2.notion.site/FE-Javascript-542dcc2333df4ef0a2fb9c478011d171?pvs=4미션가위 바위 보 앱컴퓨터가 랜덤으로 가위바위보를 출력하도록 하는 로직을 구성하는게 어려웠다. 랜덤으로 숫자를 생성하는 Math.random()을 이용하면 될 것 같은데 이 함수는 숫자만 랜덤으로 만든다. 가위바위보 결과는 string이다. 어떻게 랜덤으로 출력하도록 할까 검색을 해본결과 랜덤숫자를 배열의 인덱스로 하면 컴퓨터 결과값이 랜덤으로 출력될 수 있음을 알게되었다.비밀번호 생성비밀번호 문자들을 어떻게 변수에 담아야 할지 감이 잡히지 않았다. 배열 형태로 담는 것은 불편했고, 특히 문자열은 따옴표를 같이 입력해야 해서 조금 귀찮았다. 이에 더 간단한 방법이 없나 찾아봤다. charAt 메서드를 발견했다. 이를 이용하면 문자열에서 특정 위치의 문자를 반환할 수 있어서 변수를 배열 형태로 선언하지 않아도 되었다.1주차 후기타 사이트에서 자바스크립트 강의를 들은 적이 있어서 이번 워밍업 스터디는 기존에 배웠던 것을 한 번 다시 리마인드하는 기분으로 가볍게 생각해야지 했는데 이건 경기도 오산이였다. 배울 때는 겸손한 태도로 임해야 한다는 것과 지식을 아는 것과 그것을 활용하는 것은 다르다는 것을 다시 한 번 깨닫는 1주차였다.강의 들으면서 열심히 정리한다고 했는데 다음날 진도나가기 전에 복습으로 보는데 왜 적었지 하는게 있어서 강의를 집중하고 이해하는 것도 중요하지만 정리할 때도 미래의 나 자신을 위해 정확하게 적어야 하는것도 중요함을 알게되었다.

웹 개발워밍업클럽프론트엔드FE1주차발자국

슬프구나

인프런 워밍업 클럽 스터디 1기 FE - 1주차 발자국

인프런 워밍업 클럽이 스터디 1기 FE 를 시작한지 어느덧 1주차현재 과제 1~7까지 완료를 해놓은 상태다.음식 메뉴 앱가위 바위 보퀴즈책 리스트 나열Github Finder비밀번호 생성타이핑 테스트 과제들을 진행하면서, DOM API 에 대한 복기를 할 수 있어서 좋았다. 그리고 퀴즈 및 타이핑은 이런저런 로직을 고민하게 해줘서 좋았다. 퀴즈는 처음에 뭔가 가상의 데이터를 통해서 처리를 해야하는줄 알았다.(실제 현업에서는 DB에 문제은행식으로 관리하는걸로 알고 있다.)이걸 Math 객체를 생성하여 랜덤하게 문제와 정답을 생성하는 방식으로 처리하였다.Math.random() 함수는 0~1 사이의 난수를 발생 시킨다.(1은 포함하지 않는다)Math.random() * 10; 을 하게된다면 0~9까지의 난수를 얻을 수 있다. 이때 소수점 이하를 버려주면 정수값을 추출하는거다.그러면, 1~10까지를 얻고싶다면 어떻게 해야할까? 간단하다.min = 1;max = 10;(Math.random() * (max - min + 1) + min);max - min + 1 = 100 ~ 9 까지 난수를 얻을 수 있다. 그럼 여기에, 소수점 버린 정수에 min 을 더해주면?1~10 까지가 되는거다. 그리고 반복되는 UI 는 template 요소를 활용하여 처리 하였다.<template id="myTemplate"> <p>This is a template. It will not be rendered.</p> </template>template 요소는 렌더링 되지 않는다. 렌더링 하려면, JS로 무조건 조작을 해줘야 한다.물론 DOM Node 를 조작할 때, 원본 Node 에 영향을 끼치지 않으려면 cloneNode 또는 importNode 등으로 조작을 해줘야 한다. 마무리하며변수와 데이터 타입: 자바스크립트의 기본적인 변수 선언부터 시작하여, 다양한 데이터 타입(문자열, 숫자, 객체 등)을 배웠습니다.함수: 함수의 기본적인 선언 방법과 화살표 함수 등 최신 문법에 대해서도 배웠습니다.DOM 조작: HTML 요소를 자바스크립트를 통해 조작하는 방법을 배우고, 실제로 몇 가지 프로젝트를 통해 연습했습니다.비동기 처리: Promise, async/await를 통해 비동기 처리 방법을 배웠습니다. API 호출과 같은 작업을 처리하는 방법을 실습했습니다. null 과 undefined: 둘다 원시타입이다. 하지만 typeof 로 null 을 출력해보면 object 를 출력한다. 이는 JS 초기 설계 오류가 지금까지 이어져온것이며 웹 호환성을 위해 수정을 하지 않았다. 그러니 null 은 체크할때 이 특성을 기억해야 한다.자바스크립트 공부를 통해, 단순히 코드를 작성하는 것 이상의 귀중한 경험을 하였다. 문제 해결 능력, 창의적 사고, 그리고 끊임없는 학습의 중요성을 깨닫게 되었으며, 앞으로도 지속적으로 새로운 기술을 배우며 성장해 나갈 것이다.

웹 개발인프런워밍업클럽FE1기회고

송세연

[인프런 워밍업 스터디 클럽 1기 프론트엔드] 1주차 발자국

학습 내용호이스팅이번에 강의를 통해 호이스팅이라는 걸 처음 알게 됐는데, 꽤 흥미로운 개념이었다. 그런데 실제 예제를 찾아보니 내가 제대로 이해하고 있지 않은 것 같다는 생각이 들어서, 관련 내용을 좀 더 찾아보게 되었다.// 1. let a; console.log(a); a = 3; // 2. console.log(a); let a = 3; // 3. console.log(a); var a = 3; 1, 3번의 경우 undefined가 출력되고, 2번의 경우 참조 에러가 발생한다. 왜 이런 결과가 나오는지를 이해하고 설명할 수 있다면 당신은 호이스팅에 대해 제대로 이해한 것이다.자바스크립트를 실행시키는 인터프리터는 변수를 생성하는 단계를 선언단계와 할당 단계로 분할한다. 코드를 실행하기 전 변수의 선언 부분은 현재 범위의 맨 위로 호이스팅 된다.  이 때, 호이스팅된 var 변수는 undefined 값이 할당된다. 이것이 3번 예제 코드가 undefined를 출력하는 이유이다. 반면, 호이스팅된 let, const 변수는 값을 할당받지 않고, TDZ 상태에 있게 된다. TDZ(Temporal Dead Zone)란 일시적 데드 존으로, 변수를 사용할 수 없는 일시적인 비활성 상태를 의미한다. 이 상태에서 변수에 접근하게 되면 참조 에러를 발생시킨다. 이것이 2번 예제 코드에서 참조 에러가 발생하는 이유이다.클래스도 let, const 변수와 동일한 메커니즘이 적용된다.마지막으로 함수의 경우에도 동일하게 호이스팅 개념이 적용된다.hello(); function hello(){ console.log("hello"); } 위와 같은 함수 선언문의 경우, 선언문 자체가 호이스팅되므로 함수 선언 전에 함수를 호출해도 정상적으로 함수를 호출할 수 있다.hello(); var hello = ()=> { console.log("hello"); } 반면 위와 같은 함수 표현식의 경우, 선언문(var hello;)만 호이스팅되므로 함수 선언 전에 함수를 호출하면 참조 에러가 발생하게 된다.CRP섹션 2에서 잠시 언급되었던 CRP(Critical Rendering Path)라는 개념이 흥미로워서 개인 블로그에 따로 정리해보았다. 게시글 링크학습 회고이번에 인프런 워밍업 클럽 스터디에 참여하면서, 내가 앞으로 공부해야 할 개념들을 많이 접할 수 있어 좋았다. 지금까지 알게된 내용을 다 정리하기엔 아직 시간이 더 필요할 것 같지만, 지금은 내게 이 과정이 계속해서 동기부여가 되어준단 것으로 충분한 것 같다.미션 중 고민했던 것5일차 미션인 Github Finder 앱을 구현하면서 한 가지 고민했던 요소가 있다. Github API를 사용할 때 사용되는 Github Token의 경우 내 명의나 다름이 없어서 남들에게 유출되면 곤란한 정보인데, 이걸 js 코드에 직접적으로 드러내지 않으면서 Live Server로 띄울 수 있게 하는 방법을 찾고 싶었다. 토큰을 .env 파일에 저장하니 Live Server로 앱을 띄웠을 때 .env 파일의 경로를 찾지 못했다.며칠간 방법을 고민해보았는데, 사실 아직도 뾰족한 수는 찾지 못했다. Live Server로 띄우려면 어쩔 수 없는 걸까…7일차 미션인 타이핑 테스트 앱을 구현하면서 가장 머리를 싸맸던 부분은 타자 입력 결과를 출력할 때 맞게 입력한 문자와 오타 문자에 각각의 스타일을 적용하는 것이었다.이 사진처럼, 예제 문자열을 사용자가 입력한 문자열과 비교하고 맞게 입력한 문자는 초록색, 오타 문자는 빨간색으로 스타일을 지정해주어야 했다.문자 하나하나를 <span> 태그로 묶는 것은 너무 투박한 방식인 것 같아서, 같은 상태의 연속된 문자를 하나의 태그에 묶는 방식으로 구현하기로 했다.이 방식대로라면 위의 입력 결과는 다음과 같은 html element로 표현되어야 한다.<span class="correct">he realized what </span> <span class="wrong">was happenin</span> <span class="correct">g and told the </span> <span>others.</span> 연속해서 같은 상태의 문자가 나타나는 경우와 그렇지 않는 경우로 나누어 로직을 처리했다.for (let i = 0; i < data[currentPhase].length; i++) { let currentState = compareLetter(e.target.value, i); if (previousState !== currentState) { screen.appendChild(currentNode); currentNode = document.createElement("span"); currentNode.setAttribute("class", currentState); previousState = currentState; } currentNode.textContent += data[currentPhase][i]; if (i === data[currentPhase].length - 1) { screen.appendChild(currentNode); } } 이 문제를 해결하고 나니 이런 동적인 로직을 잘 구현하려면 DOM 요소를 처리하는 과정을 머릿속으로 잘 그릴 수 있어야겠다는 생각이 들었다.주차 회고학교 생활과 병행하려니 생각보다 커리큘럼이 많이 벅차서, 시간관리에 좀더 신경을 써야할 것 같다. 그럼에도 첫 주차를 잘 마무리한 나 자신을 칭찬하고 싶다.마지막으로 프론트엔드를 공부했던 게 제작년 겨울이었는데, 그 사이 잊어버렸던 자바스크립트 개념들이 강의를 들으며 새록새록 떠올라서 좋았다.부족한 기본기를 채우고자 시작한 활동이었는데, 강의 컨텐츠도 매우 만족스럽고 기존에 몰랐던 새로운 내용을 배워 나가는 게 즐겁다.남은 기간동안에도 끝까지 포기하지 않고 잘 마무리지을수 있도록 열심히 해야겠다.

프론트엔드

손예지

[인프런 워밍업 클럽 스터기 1기] BE 1주차 <첫 번째 회고록>

강의 요약Day 2 <서버 개발을 위한 환경 설정 및 네트워크 기초>새로운 스프링 프로젝트 시작 방법spring initializer 접속Project: 이 프로젝트에서 사용될 ‘빌드 툴’ → 최근에는 Gradle 많이 사용Language: 서버를 개발할 때 사용할 언어 → 최신 프로젝트에는 Kotlin을 사용하는 경향이 있지만 Java로 만들어진 기존 프로젝트가 많이 존재Spring Boot: 스프링 부트의 버전을 고르는 항목 → 알파벳이 붙어 있으면 개발 중이거나 오픈 베타라는 의미, 시간이 지나면서 계속 버전이 업그레이드 되기 때문에 강의를 보는 시점에 따라 다른 숫자가 나올 수 있음버전은 첫 번째 숫자(major), 두 번째 숫자(month), 마지막 숫자(버그 및 간단한 기능 추가)Project MetadataGroup: 프로젝트 그룹Artifact: 최종 결과물 이름Name: 프로젝트 이름Description: 프로젝트 설명Package name: 패키지 이름Packaging: Spring Boot 톰캣이 내장되어 있어 Jar을 선택하면 됨Java: 기존에 존재하는 프로젝트는 Java11이 가장 많고 그 다음은 Java8이 많음 → 최신 프로젝트는 최신 Java 버전을 사용할 수 있음Dependencies: 프로젝트에서 사용하는 라이브러리 / 프레임워크라이브러리: 프로그래밍을 개발할 때 미리 만들어져 있는 기능을 가져다 사용하는 것프레임워크: 프로그래밍을 개발할 때 미리 만들어져 있는 구조에 코드를 가져다 끼워 넣는 것@SpringBootApplication과 서버어노테이션: Java의 문법으로 @ 뒤에 이런저런 문자열을 붙이는 것, 스프링을 실행하기 위해 필요한 다양한 설정들을 모두 자동으로 해 줌Server: 어떠한 기능을 제공하는 프로그램 (컴퓨터)서버와 요청: 기능을 제공하기 위해서는 누군가의 요청 필요네트워크란 무엇인가택배 시스템 <-> 네트워크집 <-> 컴퓨터주소 <-> IP주소 별칭 <-> 도메인 이름택배를 받는 사람 <-> port / 3000HTTP와 API란 무엇인가HTTP(HyperText Transfer Protocol)Protocol: 표준, 약속웹을 통한 컴퓨터 간의 통신은 HTTP라는 표준화된 방식이 있음HTTP MethodHTTP 요청은 HTTP Method(GET, POST)와 Path(/portion)가 핵심GET: HTTP 요청을 받는 컴퓨터에게 요청하는 행위 → 데이터를 달라POST: HTTP 요청을 받는 컴퓨터에게 요청하는 행위 → 저장하라 GET: 데이터를 달라, 쿼리DELETE: 데이터를 삭제하라, 쿼리POST: 데이터를 저장하라, 바디PUT: 데이터를 수정하라, 바디API(Application Programming Interface)클라이언트와 서버는 HTTP를 주고받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 함정해진 약속을 하여 특정 기능을 수행하는 것 URL(Uniform Resource Locator)<http://spring.com:3000/portion?color=red&count=2>HTTP Status CodeHTTP/1.1 200 OK Content-Type: application/json { "name":"A", "age":null } 200 → OK300 → Moved Permanently400 → NotFound500 → Internal Server Error요청에서 응답은 상태 코드가 핵심GET API 개발 및 테스트API를 이루고 있는 요소HTTP MethodHTTP Path쿼리 (Key & Value)API의 반환 결과덧셈 API 생성HTTP Method: GETHTTP Path: /add쿼리: int number1 / int number2API의 반환 결과 -> 숫자 (두 숫자의 덧셈 결과)@RestController: 주어진 Class를 Controller로 등록, API의 입구@GetMapping("/add"): 함수를 HTTP Method가 GET이고 HTTP Path가 /add인 API로 지정@RequestParam: 주어지는 쿼리를 함수 파라미터에 넣음Day 3 <첫 HTTP API 개발>POST API 개발 및 테스트GET API에서 데이터 받기: 쿼리 이용POST API에서 데이터 받기: HTTP Body 이용JSON(JavaScript Object Notation): 객체 표기법, 무언가를 표기하기 위한 형식으로 중괄호가 양쪽에 있음곱셈 API 생성HTTP Method : POSTHTTP Path: /multiplyHTTP Body (JSON)API 반환 결과: 숫자 (곱셈 결과)유저 생성 API 개발유저 등록 APIHTTP Method: POSTHTTP Path: /userHTTP Body (JSON)결과 반환 X유저 조회 APIHTTP Method: GETHTTP Path: /user쿼리: 없음결과 반환 (JSON)Day 4 <기본적인 데이터베이스 사용법>Database와 MySQLDatabase: 데이터를 구조화 시켜 저장RDB(Relational Database) - MySQL: 데이터를 표처럼 구조화 시켜 저장SQL(Structured Query Language): 표처럼 구조화된 데이터를 조회하는 언어MySQL 접근 방법 -> MySQL Command List Client (무료)MySQL에서 데이터베이스 생성데이터베이스 생성create database [데이터베이스 이름];데이터베이스 목록 조회show databases;데이터베이스 삭제drop database [데이터베이스 이름];데이터베이스 안으로 접속use [데이터베이스 이름];테이블 생성create table 테이블 이름 ( ... );테이블 제거drop table [테이름 이름];MySQL Type정수: tinyint, int, bigint실수: double, decimal(A,B)문자열: char(A), varchar(A)날짜, 시간 타입: date, time, datetime테이블 데이터 조작C.R.U.DCreate, Retrieve or Read, Update, Delete데이터 넣기INSERT INTO [테이블 이름] (항목) VALUES (값);데이터 조회SELECT * FROM [테이블 이름];데이터 수정UPDATE [테이블 이름] SET 항목 = 값;데이터 삭제DELETE FROM [테이블 이름] WHERE 항목 = 값;Spring에서 Database 사용Spring <-> MySQL 연동을 위한 yaml 파일 작성spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: driver-class-name: com.mysql.cj.jdbc.Driver이후 유저 테이블 생성, jdbcTemplate를 이용하여 POST API 변경, GET API 변경, 데이터 입력 및 조회Day 5 <데이터베이스를 사용해 만드는 API>유저 업데이트 API, 삭제 API 개발과 테스트유저 이름 업데이트HTTP Method: PUTHTTP Path: /userHTTP Body (JSON)결과 반환 X (HTTP Stauts 200)유저 삭제HTTP Method: DELETEHTTP Path: /user쿼리 사용: 문자열 name결과 반환 X유저 업데이트 API, 삭제 API 예외 처리하기SELECT문으로 해당 id나 name을 가진 사용자를 조회한 다음 그 사용자가 없을 시 IllegalArgumentException()으로 예외 처리Day 6 <클린코드의 개념과 첫 리팩토링>좋은 코드(Clean Code)는 왜 중요한가코드: 요구사항을 표현하는 언어개발자: 요구사항을 구현하기 위해 코드를 읽고 작성Controller에서 모든 기능을 구현하면 안 되는 이유함수는 최대한 작게 한 가지 일만 수행하도록 하는 것이 좋음클래스는 작아야 하며 하나의 책임만을 가져야 함Controller를 3단 분리하기Controller의 함수 1개가 하고 있던 역할API가 진입 지점으로써 HTTP Body 객체 변환 -> Controller 역할현재 유저가 있는지 없는지 확인하고 예외 처리 -> Service 역할SQL을 사용해 실제 Database와의 통신 담당 -> Repository 역할회고부트캠프를 수료한 지 오래되어서 JAVA의 대부분을 까먹었다고 봐도 무방한데 실무에 필요한 부분을 먼저 배우고 기초 지식을 채워나가는 것도 효율적인 방법이라 판단되어 스터디를 시작하게 되었습니다. 아직 알아야 할 것이 더 많지만 애매하게 알고 있었던 부분에 대해 상당히 많이 이해가 되어 신기했고 앞으로의 방향성에 대해서도 고려해 볼 수 있는 1주차였습니다.

백엔드인프런워밍업클럽스터디발자국

aabb

4-29 | 피그마 베리어블과 디자인 토큰/ 디자인 시스템 개념이해하기

● 배리어블 과 스타일 배리어블은 하나의 변수만 저장 가능하며 참조할 수 있다. 따라서 기본 디자인 요소를 적용할 때 주로 사용된다.스타일은 다수의 변수까지도 저장이 가능하며 참조할 순 없다. 따라서 다수의 디자인 요소를 적용할 때 사용된다. ● 배리어블의 역할 배리어블은 디자인 토큰 및 프로토타이핑 기능을 한다. *디자인 토큰이란?디자인 시스템의 기본 구성 요소로서, 전자(Electrons)에 해당한다. /디자인 토큰이 필요한 이유많은 디자이너와 함께 작업할 때 일관성을 유지 할 수 있음다양한 플랫폼 환경(IOS, ANDROID등)에 공통된 디자인을 적용할 수 있음라이트 모드, 다크 모드 등 명확하게 색상을 구분해야 할 때 용이함 많은 하위 브랜드들이 존재할 때 디자인 에셋을 관리하기 용이함*디자인 시스템이란?재사용 가능한 컴포넌트와 패턴 등을 말하며,1) 디자인 원칙/철학 2) 스타일 가이드 3) 컴포넌트 라이브러리 4) 패턴라이브러리 5) 문서화 6) 시스템 관리 운영 으로 구성된다. *Atomic Design이란?디자인 시스템 방법론으로, 전자(Electorns) → 원자(Atom) → 분자(Molecules) → 유기체(Organisms) → 템플릿(Templates) → 페이지(pages)로 UI 시스템을 구성한다는 개념 이다. /전자(Electrons) ex. 색상, 타이포그래피, 테두리 , 그림자효과원자(Atom) ex. 라벨, 텍스트 필드, 버튼

UX/UI볼드UX워밍업클럽

개발자 경제신문 읽기 14일차

 최수연 "라인 매각 압박 따를 이유 없다"일본 정부의 압박을 정면으로 돌파하겠다는 뜻을 밝힘IT 인프라 위탁 업무를 분리하라는 행정지도는 일부 수용하기로 함. 라인 야후에 제공한 IT 인프라 분리할 것2023년 11월 개인정보 유출 사건 빌미 다만 2차 행정지도로 지분 정리 요구는 전례가 없음라인야후 최대주주는 A 홀딩스(64.5%), A홀딩스는 네이버-소프트뱅크 50%씩 출자한 JV소프트뱅크가 1주라도 가져가면 네이버는 경영주도권 X "어른이들, 철들지마"... '만 18세 이상' 레고 쏟아진다저출생 직격탄 맞은 완구업계, 틈새시장 공략을 위해 사업 차별화키덜트족을 타겟으로 한 완구 제품군 확대영포티 40대 : 레고코리아이 키덜트 레고 시리즈, 애니메이션 및 영화 IP 를 활용한 제품군 등레고 판매량 가운데 성인 비중이 20% 이상, '철들지마 레고 팝업스토어' 성수 오픈친환경 , 해외시장 모색오로라 월드 : 친환경 인형 등 현지 맞춤형 제품. 폐페트병 활용하여 지구온난화 타격 생물을 캐릭터로.(친환경은 아님) 오로라 CC 개장(강원도 원주) 라면, 과자 용량 몰래 줄이면 '과태료'슈링크플레이션 : 양을 줄이는 '슈링크', 물가상승 '인플레이션 합성어. 제품값은 그대로, 용량을 줄여 가격 인상 효과를 내는 행위포장 표시, 홈페이지 게시, 판매 장소에 게시 . 중하나를 선택해 의무화. 단, 용량 변동 비율이 5% 미만이면 의무 제외 은행 임원 출신도 속아...노후자금 다 날렸다 '눈물'60대 이상 개인파산 사유 중 주식, 코인 등 투자 실패 비율이 3년사이 4.5배 급증 - 고령자 사기 범죄 노출 대책 시급60대 이상 사기 범죄 피해자 (2018년 2.7만명 -> 2022년 4.6만명)노인 금융 교육은 생존권 차원에서 필수임 10년 기다린 한국 타이어... M&A 로 미래차 '트리플악셀'세계 2위 자동차 공조 시스템 기업 '한온시스템' 최대 주주'가 됨 - 전기차 시대 대비 차원한국터이어 : 전기차용 고부가가치 타이어 + '아트라스' 배터리 제조 역량 + 한온시스템 '공조 시스템' = 전기차 기술 3가지 보유!전기차의 안정성을 위해 열관리는 필수. 고객사에 '토탈 패키지' 제공 가능 우리금융, 10년 만에 다시 증권업 재진출우리투자증권(2013년에 농협금융지주에 매각, 현 NH투자증권) 이 다시 진출!한국포스증권 + 우리종합금융 합병 - 국내 10위 투자은행으로 키우겠음포스증권 : 온라인 펀드 판매 서비스 플랫폼(펀드 슈퍼마켓). 한국증권금융이 지분 51.68%우리종금의 기업 금융 + 포스증권의 디지털 중심 리테일 기반 결합! -> 디지털 부문 최고 증권사로 성장할 것밴처 캐피탈 - 캐피탈 - 은행 - 증권 - 자산운용 - 사모투자사 - 부실채권 전문 투자사 로 이어지는 기업 생애주기별 금융 서비스 체제 완성! '테슬라가 하면 우리도 한다'... 현대차, 1조 3천억 승부수미국 자율주행 합작법인 모셔널(현차+앱티브) 지분 66% 확보, 독자적인 자율주행 생태계 구축 발판 마련유상증자, 지분매입으로 지분 확보. 관객이 없다 ... CJ, 롯데, 지방 영화관 줄폐업롯데컬처웍스, CJ CGV 등 멀티플렉스 영화관 운영사들, 재무주고 개선을 위해 지방 상영관 문을 닫고 있음극장 건물 소유주인 자산운용사들과 일반적으로 20년짜리 초장기 임대차 계약을 하는데 절반도 안되어서 파기하는 상황롯데컬처웍스 대전 둔산점 폐점을 위해 법적 공방CGV, 2034년까지 남아있는 임대차 계약 해지 협의 요청영화관 인테리어는 스크린, 음향시설, 좌석 등을 갖추고 있어 임차인이 나가면 일반음식점, 카페로 활용하기 어렵다2019년 회계 기준 변경으로, 장기임차한 영화관을 모두 '리스부채'로 계상, 부채 상승  

교양신문읽기

구르밍

인프런 워밍업 클럽 BE 1기 - 1주차 발자국

1강spring.io ⇒ springboot 프로젝트 만들기spring boot는 톰캣이 내장되어 있음 (Packaging - Jar)2강 @SpringBootApplication과 서버@ → 어노테이션@SpringBootApplication ⇒ 자동으로 설정서버란 ?: 기능을 제공하는 것, 어떠한 기능을 제공하는 프로그램, 그 프로그램을 실행시키고 있는 컴퓨터기능을 제공하기 위해서는 누군가의 요청이 있어야 한다.3강 네트워크란 무엇인가?각각의 PC에는 고유 IP 존재IP를 모두 외우기 어렵기 때문에 도메인 이름을 사용 (ex - naver.com / spring.com ) ⇒ DNS (Domain Name System)4강 HTTP와 API란 무엇인가?데이터를 주고 받는 표준이 존재HTTP (HyperText Transfer Protocol)GETPOSTPUTDELETEAPI (Application Programming Interface): 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다.URL (Uniform Resource Locator)HTTP 응답 코드2003004005005강 GET API 개발하고 테스트하기@RestController→ API의 진입지점 만들기@RestController를 사용하면 API의 진입지점인것을 알수 있다.6강 POST에서는 데이터를 어떻게 받을까 ?HTTP Body를 이용!10강 Database와 MySQL컴퓨터의 핵심 부품CPU : 연산RAM : 임시 기억장치DISK : 장기 기억장치DatabaseRDB (Relational Database)SQL (Structured Query Language)MySQL 접근intellij ultimateCLImysql -u root -p11강 MySQL에서 테이블 만들기 DDL (Data Definition Language)데이터베이스 만들기create database [데이터베이스 이름];데이터베이스 목록보기show databases;데이터베이스 지우기drop database [데이터베이스 이름];데이터베이스 안으로 들어가기use [데이터베이스 이름];테이블 목록 확인하기show tables;테이블 만들기create table [테이블 이름]([필드1 이름][타입][부가조건],[필드2 이름][타입][부가조건],…primary key ([필드이름]));create table fruit (id bigint auto_increment, name varchar(20), price int, stocked_date date, primary key (id)); 테이블 제거하기drop table [테이블 이름];MySQL 타입tinyint : 1바이트 정수int : 4바이트 정수bigint : 8바이트 정수 (21억건이상)double : 8바이트 정수decimal(A,B) : 소수점을 B개 가지고 있는 전체 A자릿수 실수char(A) : A글자가 들어갈 수 있는 문자열varchar(A) : 최대 A글자가 들어갈 수 있는 문자열date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss12강 DML (Data Manipulation Language)CRUD데이터 넣기INSERT INTO [테이블 이름] (필드1이름, 필드2이름,…) VALUES (값1, 값2,…)INSERT INTO fruit (name, price, stocked_date) values ('사과', 1000, '2023-05-01');데이터 조회, 업데이트, 삭제select * from [테이블명] where [조건]update [테이블 이름] set 필드1이름 = 값, 필드2 이름 = 값,… where [조건]delete From [테이블 이름] where [조건];13강 Spring에서 Database 사용spring 프로젝트 Resource폴더 아래에 application.yml 파일 생성spring: datasource: url: "jdbc:mysql://localhost/library" //jdbc를 이용해 Mysql에 접근 username : "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driverapplication.yml @GetMapping("/user") public List<UserResponse> getUsers() { String sql = "SELECT * FROM user"; jdbcTemplate.query(sql, new RowMapper<UserResponse>() { @Override public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); } }); }익명 클래스 사용 RowMapper@GetMapping("/user") public List<UserResponse> getUsers() { String sql = "SELECT * FROM user"; return jdbcTemplate.query(sql, (rs, rowNum) -> { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); }); }RowMapper에 option + enter ⇒ 람다식으로 변경14강 ~ 16강public void updateUser( UserUpdateRequest request) throws IllegalAccessException { boolean isUserNotExist = userRepository.isUserNotExist(request.getId()); if(isUserNotExist){ throw new IllegalAccessException(); } userRepository.updateNameUser(request.getName(), request.getId()); } public void deleteUser(String name) throws IllegalAccessException { boolean isUserNameNotExist = userRepository.isUserNameNotExist(name); if(isUserNameNotExist){ throw new IllegalAccessException(); } userRepository.deleteUser(name); }수정, 삭제 전 사용자가 DB에 존재하는 데이터인지 확인하기 위해 예외처리를 해주었다.jdbcTemplate.query ……. ⇒ List로 반환된다.isEmpty()를 붙여 boolean 타입인지 확인하도록 한 후 조건문 실행만약 존재 하지 않는 유저라면 IlleagalAccessException()이 호출된다.PostMan으로 확인한 결과홍합이란 유저가 없어서 500이 떴다!17강 좋은 코드란 무엇인가코드는 요구사항을 표현하는 언어개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다. 코드를 읽는 것은 필수적이고 피할 수 없다안좋은 코드가 쌓이면, 시간이 지날 수록 생산성이 낮아진다! Controller에서 모든 기능을 구현하면 왜 안될까?⇒ 함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.  18강. Controller를 3단 분리하기 - Service와 Repository기존 Controller의 함수 1개가 하고 있던 역할API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다. ⇒ Controller현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다. ⇒ ServiceSQL을 사용해 실제 DB와의 통신을 담당한다. ⇒ RepositoryLayered ArchitectureController ← Service ← Repository미션 & 일주일 회고미션 (1 ~ 3번째 과제)https://charm-vise-f40.notion.site/016b87f39bbe4c31991ab1c51632bd73https://charm-vise-f40.notion.site/2-372b48a579674c988a990fa4b9a14ebb?pvs=4https://charm-vise-f40.notion.site/3-212dca4aeb81494c9d63f66689b90e4f?pvs=4워밍업 클럽이 벌써 시작한 지 일주일 정도가 흘렀다.진도표에 맞춰 강의를 듣고 과제를 진행하다 보니 시간이 금방 흐른 느낌이다!!강의를 보다 보면 내가 다 아는 것 같은 느낌이 들었는데 역시 과제를 하면 내가 어느 정도 까지 이해했는지 알수있었다 ㅎㅎ두 번째 과제를 할 때에는 출력값이 JSON으로 문제에는 나와 있지만 처음에 무작정 하다 보니 나는 그냥 단순 값으로 포스트맨에 출력되었다.뭐지? 뭐가 잘못된 거지 하면서 고민하다 보니까 객체로 반환을 하면 되는 것이었다 ㅜ세 번째 과제는 강의를 들으면서 익명, 람다식 등 잘 기억이 나지 않았는데 마침 강사님께서 과제로 내주셨다나도 코딩 님의 자바 강의에 들으면서 익명함수, 람다 식을 다시 공부했다. 좀 더 익숙해질 때까지 계속 사용해 봐야겠다.아직 초반이라 그런지 사실 강의는 매우 재밌었다. 그렇지만 스스로 자바개념이 아주 부족하다고 생각하기에주말을 활용하여 자바 개념과 강의 내용을 복습해 봐야겠다!

웹 개발인프런워밍업회고

miiro

[인프런 워밍업 스터디 클럽 1기] BE 1주차 회고록

첫 번째 발자국자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]를 수강하고인프런 워밍업 클럽에 참여하여 쓰는 첫 번째 회고록입니다. 학습 내용스프링 프로젝트를 시작하는 방법과 네트워크, HTTP, API에 대한 기본적인 개념에 대해 학습하였습니다.HTTP는 데이터를 주고 받는 표준이고, 행위와 자원은 HTTP 요청을 보내기 전에 약속을 해야합니다.HTTP Method는 GET, POST, PUT, DELETE 가 있습니다. 예시로 GET는 HTTP 요청을 받는 컴퓨터에게 요청하는 행위입니다.GET 요청의 경우 /portion 이라는 요청 받는 path와 ?의 구분기호로 세부 조건인 쿼리스트링 작성합니다.GET /portion?color=red&count=2POST 요청의 경우 데이터를 저장하는 것으로 바디를 사용합니다.POST /oak/leatherDELETE는 데이터를 삭제하기 위해 쿼리스트링을 사용하고, PUT은 데이터를 수정하기 위해 바디를 사용합니다. POST API는 HTTP Body를 활용해서 데이터를 받습니다.데이터를 보낼 때는 JSON(객체표기법)을 활용합니다.key : 'value' 형태로 Java 문법 상 Map<Object, Object> 형태와 유사합니다.@PostMapping("/multiply") public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request){ return request.getNumber1()* request.getNumber2(); }위의 예시의 주요 어노테이션은 아래와 같습니다.@PostMapping : HTTP Method가 POST 이고, 요청 경로인 /path인 API를 생성합니다.@RequestBody : HTTP Body로 들어오는 JSON 파라미터로 데이터를 전달하는 객체인 DTO로 바꿔줍니다. DTO에는 JSON의 key 값이 명시되어야하며, 각 속성은 key 값과 동일하게 value도 타입에 맞게 작성합니다. Database는 데이터를 구조화시켜 저장합니다. 마치 엑셀과 비슷하게 표처럼 구조화하여 저장합니다.여기서 구조화된 데이터를 조회하는 언어를 SQL 이라고 합니다.SQL문의 예시는 아래와 같습니다.// DB 생성 create database [데이터베이스 이름]; // DB 조회 show databases; // DB 삭제 drop database [데이터베이스 이름]; // DB 사용 use [데이터베이스 이름]; // TABLE 조회 show tables; // TABLE 생성 create table [table 이름] ([필드 이름] [타입] [부가 조건], [필드 이름] [타입] [부가 조건], ... primary key([필드 이름]) ); // TABLE 삭제 drop table [table 이름];테이블 자체를 생성, 삭제, 변경, 초기화 하는 것을 DDL(Data Definition Language) 라고 합니다. 테이블의 데이터를 조작하는 것을 일명 C.R.U.D 라고 부릅니다.테이블 데이터를 조작하는 SQL문을 DML(Data Manipulation Language) 라고 합니다.데이터 삽입insert into [table 이름]([필드 이름1], [필드 이름2], ...) values (값1, 값2, ...);데이터 조회select * from [db 이름]; select [필드 이름1], [필드 이름2] from [db 이름];조건 데이터 조회select * from [db 이름] where [조건];데이터 업데이트update [table 이름] set 필드1=값, 필드2=값,... where [조건];❗ 조건문을 작성하지 않으면 모든 데이터가 바뀌니 항상 주의하자!데이터 삭제delete from [table 이름] where [조건];❗ 조건문을 작성하지 않으면 모든 데이터가 삭제되니 항상 주의하자!  과제 내용Day 1HTTP 요청을 보내기 위한 Method 중 하나인 GET API 를 만들기 위해서 어노테이션을 사용했었습니다.이를 통해 어노테이션을 사용하는 이유는 무엇인지, 또한 나만의 어노테이션을 만드는 방법에 대해 학습하게 되었습니다.처음에는 클래스 위에 붙은 @ 어노테이션은 의미를 생각하기보다는 레이어에 맞는 동작을 하기 위해서 알맞는 어노테이션을 사용할 수 있도록 암기하는 것으로만 생각하고 공부했었습니다. 자바에서 제공하는 표준 어노테이션을 다양하게 찾아봤으며, 코드가 작동되면서 reflection을 이용하여 코드를 직접적으로 호출하지 않고 코드를 제어할 수 있는 다양한 기술의 집합체라는 것을 알게 되었습니다.그리고, 유저가 직접 만드는 어노테이션을 구현해보면서 메타 어노테이션 즉, 내가 만드는 어노테이션의 유지 기간, 위치를 결정할 수 있도록 결정할 수 있는 사용자 친화적인 조작을 할 수 있다는 것을 알게 되었습니다.📋 1일차 미션 : 어노테이션의 개념과 특징 Day 2GET, POST API를 활용한 과제인데 일반적으로, GET을 사용할 때는 URL 뒤에 query를 사용하는 방식, POST를 사용할 때는 body를 사용하는 방식으로 볼 수 있습니다. 하지만 부득이하게 데이터의 양이 많이 복잡하다면 쿼리 파라미터로 받는 방식(GET)보다는 body 로 받는 방식(POST)로 변경하는 방향이 좋다는 것을 알았습니다.또한, LocalDate 타입을 string 형태로 받아 치환을 해줬는데, 스프링부트 2.x.x 버전에서 @DateTimeFormat을 활용하여 localDate를 바로 받을 수 있는 방법도 알게 되어, java 문법의 변수가 아닌 스프링에 친화적인 어노테이션을 활용하여 구현할 수 있도록 많이 접해보고 공부해야겠다는 생각이 들었습니다.📋 2일차 미션 : GET API와 POST API Day 3람다식의 등장한 이유와 람다식과 익명 클래스의 관계에 대한 내용을 중점적으로 공부하는 것이었습니다.위의 내용을 공부하면서 함수형 프로그래밍과 @FunctionalInterface, stream API와 메서드 레퍼런스에 대한 내용에 대한 연관성도 함께 예시를 만들어보면서 공부했습니다. 위의 내용은 코딩테스트를 해본 사람이면 한 번 쯤은 실습해봤을 내용이라서 쉽게 내용을 이해할 수 있을 것이라고 생각했습니다.하지만 필자의 경우 문법에 대한 내용보다는 코드를 구현할 줄만 알았습니다. 해당 내용을 공부하니 왜 만들어졌는지, 자바에서는 버전을 올라가면서 메서드를 쉽게 구현할 수 있도록 점차 단순화시키고 간결하게 표현할 수 있다는 것에 대해 면밀하게 알 수 있었습니다.📋 3일차 미션 : 익명 클래스와 람다식  회고기초 지식보다는 실제 프로젝트를 구현하기 위한 기술에 대한 내용에 중점을 두고 공부를 했었는데, 백엔드 개발을 하기 위한 서버 지식과 Java, Spring에 관한 내용을 다시 처음부터 하나씩 이해하면서 다시금 지식을 쌓을 수 있었던 거 같습니다.또한, 강의만 듣는 게 아닌 과제를 해결하면서 강의에 대한 이해와 구현할 수 있는 능력을 키우면서 나 자신의 부족한 점과 다른 방식으로 구현할 수 있을 수 있을까라는 여러 방법에 대해 골똘하게 생각할 수 있는 계기가 되었던 거 같습니다.

백엔드인프런워밍업스터디클럽1주차회고록

수희

[워밍업클럽] BE 1기 #과제3

우리는 JdbcTemplate을 사용하는 과정에서 익명 클래스와 람다식이라는 자바 문법을 사용했습니다. 익명 클래스는 자바의 초창기부터 있던 기능이고, 람다식은 자바 8에서 등장한 기능입니다. 다음 키워드를 사용해 몇 가지 블로그 글을 찾아보세요! 아래 질문을 생각하며 공부해보면 좋습니다! 😊 [키워드]익명 클래스 / 람다 / 함수형 프로그래밍 / @FunctionalInterface / 스트림 API / 메소드 레퍼런스 [질문]자바의 람다식은 왜 등장했을까?람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?익명 클래스란? 클래스 선언과 객체 생성을 동시에 하며 단 한번만 사용되는 일회용 클래스이다.클래스를 별도로 선언하지 않아도 되어 기존보다 간결하게 코드를 작성할 수 있게 되었지만, 그럼에도 작성해야할 부분이 많다는 불편함을 가지고 있다.람다식을 사용하여 익명 클래스보다 더욱 간결한 코드 작성이 가능해졌다.Collections.sort(words, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } });Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));람다식이란? 메서드를 하나의 식으로 표현하는 것으로 메서드 이름과 반환값이 없으므로 익명 함수라고도 한다.람다식의 도입으로 기존의 자바를 거의 변경하지 않고도 함수형 언어의 장점을 접목시킬 수 있게되었다.함수형 프로그래밍이란? 선언형 프로그래밍의 일종으로 순수 함수를 조합하고 프로그래밍 패러다임이다. 순수 함수는 입력 파라미터에만 의존하며, 부수 효과를 일으키지 않는 함수를 뜻하며 정의된 API를 통해서만 외부 시스템과 상호작용하여 결과를 만들어내는데 이러한 부분이 객체지향 언어와는 다른 점이다.함수형 프로그래밍 장점테스트와 디버깅에 용이함간결한 코드 작성개발 생산성코드 가독성에 좋음함수 단위 코드 재사용 쉬움 람다식과 익명 클래스 둘 다 함수 객체를 만들 때 사용한다. (함수 객체란 추상 메서드를 하나만 담은 인터페이스의 인스턴스를 말한다. ) 하지만 람다식과 익명 클래스가 같다고 할 수 없다. 람다는 다음 3가지 한계점을 가지고 있다.추상클래스의 인스턴스를 만들 때는 람다 사용 불가능추상메서드가 여러개인 인터페이스의 인스턴스로 람다 활용 불가능람다는 자기자신을 참조하지못함 문법 >(매개변수목록) -> {함수몸체}1. 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략 가능함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략 가능 (이때 세미콜론(;)은 붙이지 않음)매개변수가 하나인 경우에는 괄호(())를 생략 가능4. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략 불가능 예시 >int max(int a, int b) { return a > b ? a : b ; }(a,b) -> a > b ? a : b int sumArr(int[] arr) { int sum = 0; for(int i : arr) sum += i; return sum; }(int[] arr) -> { int sum = 0; for(int i: arr) sum += i; return sum; }강의- 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지], https://inf.run/XKQg출처자바의정석 14장 람다와 스트림https://code-lab1.tistory.com/245https://yozm.wishket.com/magazine/detail/2023/https://limkydev.tistory.com/226https://coder-in-war.tistory.com/entry/Java-24-%EC%9D%B5%EB%AA%85%ED%81%B4%EB%9E%98%EC%8A%A4%EB%B3%B4%EB%8B%A4%EB%8A%94-%EB%9E%8C%EB%8B%A4 

김동찬

인프런 워밍업 클럽 3일차 과

Q1- 람다식의 등장이유Stream 연산들은 매개변수로 함수형 인터페이스(Functional Interface)를 받도록 되어있다. 그리고 람다식은 반환값으로 함수형 인터페이스를 반환하고 있다. 그렇기 때문에 우리는 Stream API를 정확히 이해하기 위해 람다식과 함수형 인터페이스에 대해 알고 있는것이 좋다. 익명함수(Anonymous Function)란 함수의 이름이 없는 함수로, 익명함수들은 모두 일급 객체이다. 일급 객체인 함수는 변수처럼 사용가능하며 매개 변수로 전달이 가능하는 등의 특징을 가지고 있다.   기존의 방식에서는 함수를 선언할 때 다음과 같이 선언하였다. // 기존의 방식 반환티입 메소드명 (매개변수, ...) { 실행문 } // 예시 public String hello() { return "Hello World!"; } 하지만 람다 방식으로는 위와 같이 메소드 명이 불필요하며, 다음과 같이 괄호() 와 화살표-> 를 이용해 함수를 선언하게 된다. // 람다 방식 (매개변수, ... ) -> { 실행문 ... } // 예시 () -> "Hello World!"; 이렇게 람다식이 등장하게 된 이유는 불필요한 코드를 줄이고, 가독성을 높이기 위함이다. 그렇기 때문에 함수형 인터페이스의 인스턴스를 생성하여 함수를 변수처럼 선언하는 람다식에서는 메소드의 이름이 불필요하다고 여겨져서 이를 사용하지 않는다. 대신 컴파일러가 문맥을 살펴 타입을 추론한다. 또한 람다식으로 선언된 함수는 1급 객체이기 때문에 Stream API의 매개변수로 전달이 가능해진다.   람다식(Lambda Expression) 의 특징 람다식 내에서 사용되는 지역변수는 final이 붙지 않아도 상수로 간주된다. 람다식으로 선언된 변수명은 다른 변수명과 중복될 수 없다. 람다식(Lambda Expression) 의 장점 코드를 간결하게 만들 수 있다. 식에 개발자의 의도가 명확히 드러나 가독성이 높아진다. 함수를 만드는 과정없이 한번에 처리할 수 있어 생산성이 높아진다. 병렬프로그래밍이 용이하다. 람다식(Lambda Expression) 의 단점 람다를 사용하면서 만든 무명함수는 재사용이 불가능하다. 디버깅이 어렵다. 람다를 남발하면 비슷한 함수가 중복 생성되어 코드가 지저분해질 수 있다. 재귀로 만들경우에 부적합하다. ☞ 람다라고 무조건 좋은건 아니다. 상황에 맞게 적절하게 사용하자:) Q2 람다식과 익명 클래스의 관계 익명클래스가 필요한 상황1. 프로그램 내에서 일시적으로(단발성으로) 한번만 사용되어야 하는 객체일 경우-> UI 이벤트처리, 스레드 객체 등 (단발성 이벤트 처리)2. 재사용성이 없고, 확장성을 활용하는 것이 유지보수에서 더 불리할 때-> 비즈니스 로직이 정말 재각각이며, 재사용성이 전혀없어 매번 클래스를 생성해야하는 비용이 더 많을 때정리하자면 클래스를 별도로 만들 필요없이 코드에서 익명객체를 생성/정의하여 단 한번의 쓰임을 다하고 소멸한다.그래서 만일 어느 메소드에서 부모 클래스의 자원을 상속받아 재정의하여 사용할 자식 클래스가 한번만 사용되고 버려질 자료형이면, 굳이 상단에 클래스를 정의하기보다는, 지역 변수처럼 익명 클래스로 정의하고 스택이 끝나면 삭제되도록 하는 것이 유지보수면에서나 프로그램 메모리면에서나 이점을 얻을 수 있다. 다만 주의해야 할 점이 있다.기존의 부모 클래스를 상속한 자식 클래스에서는 부모 클래스의 메서드를 재정의 할뿐만 아니라 새로운 메소드를 만들어 사용할수 도 있다는 점은 다들 알고 있을 것이다.하지만 익명 클래스 방식으로 선언한다면 오버라이딩 한 메소드 사용만 가능하고, 새로 정의한 메소드는 외부에서 사용이 불가능 하다.이런 익명클래스중 익명클래스 중에서 한 가지 메소드만 구현하는 경우, 람다식으로 변경할 수 있다.둘 다 함수적 프로그래밍을 구현하는 방식이지만 람다식는 앞서 말했듯이 익명 클래스의 단점을 보완하기 위해 등장했음. 람다식은 익명 클래스보다 간결하고, 가독성이 높으며, 함수적 프로그래밍 적용이 쉽고, 스코프 개념으로 감싸고 있는 변수를 직접 참조가 가능하며 마지막으로 직렬화도 가능함. 출처: https://itkjspo56.tistory.com/289 [로춘남의 IT이야기:티스토리]

백엔드