삼성 청년 SW 아카데미를 다니면서 도전했던 2번의 B형, Professional 시험 중 한 번은 합격 가능성이 있었던,, 아까운 기억이 있다. 그 때 문제가 아마 그래프 축소 + 다익스트라였던 것으로 기억하는데 아쉽게 다익스트라 알고리즘을 몰라 BFS로 선회, 불합격했었다.
그 이후로도 다익스트라, 프림, 크루스칼 알고리즘 등이 내 발목을 계속 잡길래 학습의 필요성을 느꼈어서, 이번 코드트리 조별과제 이벤트에 참여해 학습해보고 있는데 코드트리 이거,, 참 물건이다. 알고리즘을 학습하면서 가장 불편하고 어려웠던 부분이 동일 알고리즘의 다른 유형 문제를 찾는 것이었는데 코드트리를 쓰면 그런 문제를 안 찾아도 된다는게 정말 편해서 취직 전까지는 사용할 것 같다. 개인적으로 결제할 의향 O
다익스트라 관련 개념과 문제 풀이를 진행 중이다. 정리한 내용을 일부 공유하면
정의 : 시작점부터 모든 정점으로 가는 최단거리를 구하는 알고리즘. 음수 가중치가 없어야 한다
시간 복잡도 : O(ElogV) = 인접 리스트, O(V^2) = 인접 행렬
이 정도는 알고 있었는데, 아래 내용이 참 좋다.
모든 정점으로부터 특정 도착점
특정 시작점에서 특정 도착점
사전순으로 가장 앞선 최단거리
위와 같은 유형에 대해 다익스트라를 어떻게 활용할 것인가? 에 대한 고민을 하게 되는 계기였달까.. 아직 다익스트라와 어사지만 점점 친해지는 중이다.
SSAFY, 싸피는 삼성 청년 SW 아카데미의 줄임말로 문제 해결능력을 갖춘 경쟁력 있는 차세대 SW인력을 키우는 교육 프로그램으로 최고 수준의 맞춤형 교육, 자기주도적 학습, 효율적인 취업지원 서비스를 제공하는 싸피는 5개 캠퍼스에서 많은 인원을 교육하고 있습니다. ( 10기 기준, 1000명 이상 - 서울, 대전, 광주, 구미, 부울경 캠퍼스 ) 이 외에도 교육지원금 지급, 국내외 연구소 실습 기회, 우수 교육생 시상, 통학버스 운행(서울 제외) 등을 지원합니다.
SSAFY 지원 자격
* 전공 무관 * SW 관련 전공생, 비전공생 모두 지원 가능 !!
만 29세 이하, 국내외 4년제 대학(학사 이상) 졸업자 및 졸업 예정자(23년 8월), 현재 미취업자 대상이며
인터뷰일부터 본교육 시작일 전까지 재직(예정)자 지원불가
교육시작일 교육 입과 가능한 자
입과 후 1년간 SSAFY 교육에 온전히 집중할 수 있는 자
교육기간 중 통학 가능한 자(별도 숙소 제공 없음)
병역필 또는 면제자로 해외여행에 결격 사유가 없는 자
Tip 1. 교육 시작일 이전 전역자도 졸업 또는 졸업 예정자라면 지원 가능! 실제로 학점은행제를 이용해 부대 안에서 졸업 후 갓 전역한 상태로 교육에 참여하는 케이스도 있습니다 🔥
SSAFY 교육생 선발 절차
SSAFY는 1년에 2번(상반기, 하반기) 선발하며 10기 기준 선발 일정은 아래와 같습니다.
지원서 접수 4.24(월) ~ 5.8(월)
SW적성진단 SW비전공 : 5.13(토), SW전공 : 5.21(일)
인터뷰 6.7(수) ~ 6.13(화)
입과 및 교육 23년 7월 시작
SSAFY 꿀팁 및 합격 인증
우선 합격 인증부터 !
> 10기 합격 인증 <
SSAFY 지원 시 꼭 거쳐야 할 3관문은 바로 에세이, 적성진단, 인터뷰!
각 관문당 하나씩 꿀팁 풀어보겠습니다.
에세이 꿀팁 - 본인 소개와미래의 내 모습 포함하기
에세이를 쓰는 이유는 인터뷰 기회를 얻기 위함입니다. 그러기 위해서는 지원자가 알고 싶은 사람이 되어야 합니다.
Place, Time, Bookmark, Title, Company, EndDate, Pay라고 해봅시다.
이 때, StudyArticle 컴포넌트는 어떻게 될까요?
import Place from 'Place';
import Time from 'Time';
import Bookmark from 'Bookmark';
import Title from 'Title';
import Company from 'Company';
import EndDate from 'EndDate';
import Pay from 'Pay';
// 아무런 스타일을 적용하지 않았을 때
function StudyArticle() {
return (
<article>
<Place />
<Time />
<Bookmark />
<Title />
<Company />
<EndDate />
<Pay />
</article>
);
}
// 스타일을 적용할 때
function StudyArticle() {
return (
<article>
<Flexbox>
<Place />
<div>
<Time />
<Bookmark />
</div>
</Flexbox>
<Company />
<Title />
<Flexbox>
<EndDate />
<Pay />
</Flexbox>
</article>
);
}
이런 식으로 표현할 수 있을 것 같아요.
자, 여기서 각자 atomic 컴포넌트로 분리했어요. 그렇다면 데이터는 어떻게 관리해야 할까요?
가장 쉬운 방법은 StudyArticle에서 props로 내려주는 것이겠죠? 해봅시다.
import Place from 'Place';
import Time from 'Time';
import Bookmark from 'Bookmark';
import Title from 'Title';
import Company from 'Company';
import EndDate from 'EndDate';
import Pay from 'Pay';
// props는 StudyList에서 내려주고 있습니다.
function StudyArticle({ place, time, bookmark, company, title, endDate, pay }) {
return (
<article>
<Flexbox>
<Place place={place} />
<div>
<Time time={time} />
<Bookmark bookmark={bookmark} />
</div>
</Flexbox>
<Company company={company} />
<Title title={title} />
<Flexbox>
<EndDate endDate={endDate} />
<Pay pay={pay} />
</Flexbox>
</article>
);
}
자, 열심히 시간을 들여서 StudyArticle 컴포넌트를 무사히 완성했어요! 정말 기쁘네요.
기쁨을 느낄 새도 없이, 디자이너가 ‘홈 화면에서 보여질 작은 공고 UI’라는 비슷한 UI 생성 요청을 해왔어요.
음.. 이건 좀 다르네요? 북마크와 회사 위치, 마감일과 금액의 위치는 변해있고, 등록 시간은 없네요.
뭐,, 아까처럼 하면 만들 수 있지 않을까요?
이때, 디자이너가 너무 열일한 나머지 ‘마이페이지에서 보여질 공고 UI’ 컴포넌트 제작을 요청해요.
이것도 뭐 기존 스터디 UI에서 크게 벗어나지 않긴 하네요. 근데 뭔가 불안해요.
매번 비슷한 컴포넌트 제작을 요청받을때마다 중복이 너무 많은 컴포넌트를 만드는 것 같아요.
최근에 팀 프로젝트에서 6주동안 프론트엔드 2명이서 31개의 페이지를 구현하는 일을 맡았습니다. 저는 일정이 빡빡하다 보니 한 페이지 컴포넌트에 기능과 UI 모두를 기술하고 사용하고 있었어요. 나중에 분리하면 되겠지라는 안일한 마음으로
그런데 서비스를 개발하다보니 재사용성이 필요한 컴포넌트들도 많고 변경점도 많더군요. 세상에. 저는 죽었습니다 이 프로젝트를 무사히 끝낼 수 있을까? 어떻게 하면 시간이 덜 걸리면서 페이지를 구현할 수 있을까? 를 고민하기 시작했습니다.
비슷하지만 다른 페이지들을 구현하다보니 기능과 UI에 대해 공통점이 보이기 시작했고 이를 컴포넌트로 분리해서 재사용을 하자! 라고 생각하기에 이르렀습니다. 그런데 비슷한 기능임에도 다른 UI를 가지고 있거나, 기능은 다르지만 비슷한 UI를 가지고 있었습니다. 머리 아프다
얕은 복사와 깊은 복사를 알기 전에 자바스크립트의 데이터 타입과 메모리 동작을 이해하는 것이 우선이다.
데이터 타입은 크게 원시형 / 참조형으로 구분되어있고 어떤 데이터를 변수에 저장하느냐에 따라 동작이 달라진다.
원시형을 먼저 살펴보자.
// 변수 a에 숫자 1을 할당하는 예시
var a = 1;
1. &27의 값에 undefined를 할당한다. 2. 식별자 a에 &27을 할당한다. (& 기호는 메모리 주소를 의미한다. &27은 메모리의 27번 주소) 3. 새로운 공간인 &37에 1을 저장한다. 4. a에 &37을 할당한다.
원시형 데이터는 이런 방식으로 변수를 선언하고 할당한다.
참조형은 어떻게 다를까?
// 변수 obj에 객체를 할당하는 예시
var obj = { name: 'jin' }
1. &27의 값에 undefined를 저장한다. 2. 식별자 obj에 &27을 할당한다. (& 기호는 메모리 주소를 의미한다. &27은 메모리의 27번 주소) 3. 새로운 공간인 &37에 객체를 저장할 공간의 주소인 &12를 할당한다. 즉, &37번 주소의 값이 &12이다. 원시형 데이터는 &37번 주소의 값이 1이었다. 4. &12(name)에 'jin'이라는 문자열 값을 저장한다. 5. obj에 &37을 할당한다.
결과 : obj 변수의 값은 &37이며, &37에는 객체 프로퍼티를 저장하고 있는 저장 공간의 주소를 값(&12)으로 가진다. 즉, 객체는 주소값을 이용해 참조한다.
1. 복사의 종류
복사의 종류에는 세 가지가 있다.
참조 복사(reference copy), 객체 복사(object copy), 깊은 복사(deep copy)
이번에도 코드를 통해 세 가지를 알아보자.
// 중첩된 객체 예시
var nestedObject = { name : 'jin', school : { middle : 'haemi', high : 'seoil' }}
// 참조 복사
var referenceCopyObject = nestedObject
// 객체 복사
var shallowCopyObject = shallowCopy(nestedObject)
function shallowCopy(targetObject) {
var returnObj = {}
// targetObject를 순회하면서 prop-targetObject[prop](key-value)쌍으로 returnObj에 추가
for (var prop in targetObject} {
returnObj[prop] = targetObject[prop]
}
// 새로 만들어진 객체 반환
return returnObj
}
// 깊은 복사
var deepCopyObject = deepCopy(nestedObject)
function deepCopy(target) {
var returnValue = {}
// null의 타입이 object인 버그가 있습니다..
if (typeof targetObj === 'object' && target !== null) {
// 만약 타겟이 객체라면 프로퍼티를 재귀 형식으로 호출
for (var prop in targetObject} {
returnValue[prop] = deepCopy(target[prop])
}
} else {
// 타겟이 객체가 아니라면 값 반환
returnValue = target
}
return returnObj
}
가정
nestedObject(&20)의 값이 &37이고, &37이 &26(name), &11(school)의 값을 가지고 있다.
&11은 객체를 값으로 가지므로, &11은 &98(middle), &67(high)를 값으로 가진다.
&98은 'haemi'라는 문자열을 값으로 가지고, &67은 'seoil'를 가진다.
복사 결과
referenceCopy의 값
: &37, nestedObject와 똑같은 객체를 가리키는 주소를 값으로 가진다.
shallowCopy의 값
: 새로운 객체를 할당했으므로 &20의 값과 &37의 값, &26의 값이 새로운 주소로 할당된다.
단, &11은 그대로 가지고 있다. 변수에 객체를 새로 할당할 때를 생각하면 이해할 수 있다.
변수 deepCopy의 값
: &37, &26(name), &11(school), &98(middle), &67(high)의 값, 즉 모든 주소의 값이 달라진다.