프론트엔드 엔지니어로서 로그인 UI/UX를 향상시키는 방법

참고 페이지

  1. 꼭 필요한 정보만 받기
  • 사용자에게 꼭 받아야 하는 정보가 무엇인지를 따져봐야 한다
  • 아이디(이메일)을 입력하면 서버에 보내 회원인지를 판별하여 화면을 보여준다
  1. 간편 로그인(Auth 2.0)을 제공하기
  • 사용자가 키보드를 쓰지 않을 수 있는 방법이 있다면 키보드를 사용하지 않도록 디자인 하기
  • 카카오톡 / 네이버 / 페이스북 / 구글 / 트위터 등의 Auth 2.0의 활용이 필요하다
  • 생년월일, 나이 등도 키보드 없이 설정할 수 있도록 해야한다

2-1. 사용자에게 간편 로그인을 유도하기

  • X 버튼은 사용자가 누르기 어렵도록 엄지영역에서 먼 곳으로 위치시키기
  • 회원가입하면 얻는 이점을 명확하게
  • 레이블, 플레이스홀더도 할 일을 명확하게 제시
  • 텍스트 필드 밑줄에는 애니메이션이 필요
  • 텍스트 필드에 적는 내용을 실시간으로 서버에서 확인하고 판단 후에 가입/계속하기 버튼을 활성화하기
  • Auth 2.0을 더 사용하도록 엄지에 가까운 쪽으로 외부 로그인 버튼을 크게 두어 사용을 유도하기
  • Auth 2.0을 사용한다면 동의 문구를 반드시 표기
  • 경고 문구는 되도록 상냥한 문구를 쓸 수 있도록 하기

Comment and share

체력을 기르기 위한 운동은 필수! 해야 할 운동들을 정리

  • 해본 운동들 중에 효과가 좋았던 것들, 지속해서 일주일 넘게 해 봤던 운동들을 정리
  • 플레이 리스트로 정리하자니 관리가 귀찮을 것 같아서 포스팅으로 남김

1. 스트레칭

(1) 하루 5분, 30일 후엔 다리찢기가 되는 스트레치! (일본어 영상)

스트레치

(2) 고관절이 딱딱한 사람이라도 부드러워지는 스트레치 (일본어 영상)

스트레치

(3) 발목 가동성 및 강화운동을 해도 좋아지지 않는 이유

스트레치

2. 유산소 운동들

(1) 빅시스 올인원 운동

NO 층간소음 올인원 운동

(2) 땅크부부 칼소폭

칼소폭 매운맛

(3) 차머 12분 맨몸 홈트

맨몸 홈트 차머

(4) 리쌤 초보자 운동

바벨라토르 홈트

Comment and share

프론트엔드 엔지니어 면접에서 자주 나오는 질문 1편

(추후에도 정리할 수 있음 더 정리하기…)

해당 영상에서 나온 것들을 위주로 정리

1. Virtual-DOM이란?

Virtual DOM은 무엇인가요?
Virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념입니다. 이 과정을 재조정이라고 합니다.
(React 공식 문서 참조)

(1) 브라우저는 HTML을 전달 받으면 이를 파싱하여 DOM 노드로 이루어진DOM 트리를 생성한다
(2) CSS파일과 각 엘리먼트의 inline 스타일을 파싱, 스타일 정보를 사용해서 Render 트리를 생성한다
(3) 이 노드 스타일을 동기적으로 attachment하고 렌더 트리가 다 만들어지면 레이아웃(reflow) 과정을 통해 노드들에 스크린의 좌표가 주어지며 위치가 정해진다
(4) 렌더링이 끝나면 paint() 메소드를 통해 렌더링된 요소들에 색을 입힘

그렇다면 왜 Virtual DOM은 효율적인걸까?

  • DOM을 직접 조작한다면 그 때마다 레이아웃의 재계산과 리렌더링이 일어날 것
  • 이 변화가 일어날 때 Virtual DOM에서 계산한다면 이 DOM은 가상 DOM이기 때문에 렌더링되지 않고, 그렇기 때문에 연산 비용의 절감 효과가 있다
  • Virtual DOM은 DOM fragment를 관리하는 과정을 자동화 및 추상화하고 어떤 부분이 바뀌었는지를 파악해준다

velopert님 블로그를 참조함

2. useMemo와 useCallback

(1) useMemo

1
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

메모이제이션된 값을 반환합니다 (React 공식 문서)

  • 복잡한 함수의 return값을 기억해야 할 때 사용
  • 렌더링 중에 실행되므로 사이드 이펙트가 일어나는 것을 useMemo로 처리해선 안된다 → useEffect()를 사용할 것!

(2) useCallback

1
2
3
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);

메모이제이션된 콜백을 반환합니다 (React 공식 문서)

  • 불필요한 렌더링을 방지하기 위해 설계된 함수
  • 의존성을 갖는 reference(여기서는 [a, b])가 변경되었을 때 실행됨

→ 사실 useMemo()나 useCallback()은 (렌더링 최적화를 위해 사용 가능하지만) 이제 useState()와 useEffect()로 거의 다 처리할 수 있다

참고자료: React.memo() 현명하게 사용하기

3. 리렌더링의 조건

  • React에서 렌더 순서는 App → 부모 → 자식 순
  • React에서 마운트 순서는 자식 → 부모 → App 순
  • React는 컴포넌트의 상태가 변하면 컴포넌트의 리렌더링을 발생시킨다
    • 자신의 상태가 변경될 때
    • 부모 컴포넌트가 리렌더링 될 때
    • 자신이 전달받은 props가 변경될 때
    • forceUpdate()가 실행될 때

4. 자바스크립트의 실행 컨텍스트

참고 페이지

  • 실행 컨텍스트란 실행 가능한 코드를 형상화하고 구분하는 추상적 개념으로 코드가 실행되기 위해 필요한 환경
  • 실행 가능한 코드는 전역 코드, Eval 코드, 함수 코드로 나뉜다

(1) 실행 컨텍스트의 실행 과정

  • 컨트롤이 실행 가능한 코드로 이동하면 새 실행 컨텍스트가 생성된다
  • 전역 코드로 컨트롤이 진입하면 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다(이 전역 실행 컨텍스트는 웹페이지를 나가거나 브라우저를 닫을 때 까지 유지됨)
  • 함수를 실행하면 해당 함수의 실행 컨텍스트가 생성되고 직전에 실행된 코드 블록의 실행 컨텍스트 위에 쌓인다
  • 함수 실행이 끝나면 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트에 컨트롤을 반환

(2) 실행 컨텍스트의 구조

  • 실행 컨텍스트는 변수 객체(Variable Object), 스코프 체인, this로 이루어져 있다
  • 변수 객체는 변수, 매개변수, 인수정보, 함수 선언 등을 담고 있다
  • 전역 컨텍스트는 전역 함수와 전역 변수를 가지고, 함수 컨텍스트는 매개변수 객체와 내부 함수, 지역 변수를 갖는다
  • 스코프 체인은 해당 전역/함수 컨텍스트가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 전역 객체, 활성 객체의 리스트를 가리킨다
  • 실행 컨텍스트 스택 내 활성 객체를 선두로 리스트의 마지막은 당연히 전역 객체를 가리킨다
  • 자바스크립트 엔진은 스코프 체인을 통해 렉시컬 스코프(함수가 중첩될 때 상위 스코프를 따라 올라가는 것)를 파악한다
  • 자바스크립트의 함수는 호출 될 때 매개변수 인자 이외에 arguments 객체와 this를 전달 받는다
  • this는 어떤 스코프에 위치해 있느냐에 따라 다른데 전역 객체에 있다면 this는 window(브라우저), global(Node.js) 객체를 의미한다
  • 메소드의 내부함수나 콜백의 경우에도 this는 전역 객체에 바인딩 된다
  • 함수가 객체의 프로퍼티 값이라면 메서드로 호출되는데, 이 메서드 내부의 this는 해당 메서드를 호출한 객체에 바인딩된다
  • new 연산자로 생성자를 호출할 경우 자바스크립트는 빈 객체를 먼저 생성하여 this를 바인딩하고 바인딩된 this를 통해 프로퍼티를 생성하여 객체를 리턴한다

5. 클로저

  • 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어에서라면 클로저가 사용된다
  • 클로저는 반환된 내부함수가 자신이 선언되었을 때의 환경인 스코프를 기억하고 자신이 선언됐을 때의 스코프 밖에서 호출되어도 그 스코프에 접근할 수 있는 함수를 말한다
  • 말이 어려운데 클로저는 함수 안에 함수가 있게 되면 기본적으로 생성된다
  • 그렇게 되면 자연스레 스코프 체인이 형성될 텐데 이 스코프 체인이 형성될 때 변수 값들을 보존하고 기억하게 된다 (이는 메모리에서 해당 함수가 없어질 때까지 존재함)

6. 이벤트 루프와 이벤트 버블링, 이벤트 위임

참고 페이지: 이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지

  • 이벤트 버블링은 특정 화면 요소에 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되는 특성 → 이는 HTML요소가 트리 구조를 가지기 때문
  • 이런 버블링은 stopPropagation()을 통해 막을 수 있다
  • 이벤트 캡쳐는 이와 반대 방향으로 진행되는 전파 방식
  • 하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트를 제어하기 위한 것이 이벤트 위임

7. promise, async, await

자바스크립트에서 비동기 처리란?

  • 특정 로직의 실행이 끝날때 까지 기다리지 않고 나머지 코드를 먼저 실행하는 것
  • 이를 해결하기 위해 콜백 함수를 사용했었음
  • promise는 이 비동기 처리에 사용되는 객체로 Pending(대기), Fulfilled(이행), Rejected(실패)의 3가지 상태를 가진다
  • new promise()가 호출되면 대기 상태가 되며 첫번째 매개변수로 콜백 함수를 선언할 수 있으며 이 콜백 함수는 resolve와 reject 인자를 가진다
  • resolve가 실행되었을 때에 이행 상태가 되고 reject가 실행되었을 때 실패 상태가 된다
  • 이행 상태가 된다면 then()을 사용하여 처리 결과 값을 받을 수 있고 실패 상태가 된다면 catch()로 처리 결과 값을 받을 수 있다

비동기 처리 패턴에 사용되는 async와 await

  • 코드의 순서를 보장하기 위해 사용하는 예약어(async)와 연산자(await)
  • await의 처리 코드는 promise를 반환해야 한다
  • async와 await의 예외를 처리하려면 try catch문을 사용해야 한다

8. 자바스크립트의 가비지 컬렉션

  • 자바스크립트는 도달 가능성(reachability)이라는 개념을 사용해 메모리를 관리한다
  • 가비지 컬렉터는 루트 정보를 수집하고 이를 기억한다
  • 루트가 참조하고 있는 모든 객체를 방문하고 이것들을 기억한다
  • 기억한 모든 객체에 방문하여 그 객체가 참조하는 객체까지 기억한다 (한 번 방문하면 다시 방문하지 않음)
  • 루트에서 도달 가능한 모든 객체를 방문할 때까지 반복한다
  • 이 때 기억되지 않은 모든 객체를 메모리에서 삭제
  • 최적화 기법으로 세대별 수집(새로운 객체/오래된 객체로 나누어 감시), 점진적 수집(가비지 컬렉션을 나누어 수행), 유휴 시간 수집(CPU가 유휴 상태일 때만 실행) 기법을 사용함

9. www.google.com을 입력 했을 때 일어나는 일

잘 정리된 문서가 있으므로 링크만 남김

10. 브라우저가 display: none;을 처리하는 법

참고 페이지 : 렌더링 트리 생성, 레이아웃 및 페인트

  • DOM과 CSSOM 트리는 결합해 렌더링 트리를 형성
  • 페이지를 렌더링하는 데 필요한 노드만 포함시킴
  • 레이아웃을 통해 위치와 크기 계산
  • 페인트 및 픽셀 렌더링

이 때 display: none;은 요소가 보이지 않고 레이아웃에도 포함되지 않도록 렌더링 트리에서 요소가 완전히 제거됨 (visibility: hidden은 레이아웃에서 공간을 차지함)

Comment and share

[AWS Builders 프로그램] 데이터베이스 이론 및 실습

  • 교육 일자 : 2021. 04. 21(수)
  • 이 강의에서는 AWS의 완전관리형 데이터베이스인 Aurora 서비스에 대해 알아보고 실습을 진행 (오전 강의)
  • 또, 효율적인 Aurora의 활용을 위해 인터널 아키텍처의 구조를 알아보고 상세 기능의 사용법에 대해 배움 (오후 강의)

오전 강의 : AWS의 Aurora 서비스

열어보기

AWS RDS 서비스의 특징

  • 자체 관리형 DB의 경우 많은 작업들을 부담해야 하지만 AWS의 완전 관리형 DB를 사용한다면 개발자는 스키마 디자인, 쿼리 구성, 쿼리 최적화만 담당하고 그 외의 일은 AWS에서 담당하게 된다
  • AWS에서 담당하는 것은 자동 백업 및 복구, 보안 및 격리, 산업 규정 준수, 자동 패치, 모니터링, 서버 유지관리 등
  • Amazon RDS(이하 RDS)에서 제공하는 DB: Aurora, MySQL, PostgreSQL, MariaDB, SQLServer, ORACLE
  • AWS 콘솔에서 몇 분 만에 서비스에 필요한 데이터베이스를 구성할 수 있으며, 서버나 네트워크 OS, DB의 설치 등 모든 작업은 불필요함
  • DB 인스턴스에 대한 CloudWatch 지표로 모니터링이 가능하며 SNS와 연계해 이벤트가 발생할 때 경보 수신이 가능
  • 데이터베이스 성능 개선 도우미를 제공하며 로드를 유발하는 SQL문과 그 이유를 찾기에 용이함
  • 물리적으로 분리된 가용영역에 standby DB를 운영하며 동기식 복제 및 자동 Failover를 수행함
  • 또한 읽기 전용 DB를 제공(MySQL, MariaDB, PostgreSQL, Oracle에서 지원)하며, 장애 발생 시에 빠른 복구를 위해 읽기 전용 복제본을 마스터로 승격 가능함
  • 매일 전체 인스턴스에 대한 볼륨을 백업, DB변경 로그가 저장 됨 (기본 7일 최대 35일 보관)

AWS Aurora 서비스

  • 클라우드 용으로 구축된 MySQL, PostgreSQL 호환 관계형 데이터베이스
  • 3개의 가용 영역에 복제본을 하나씩 갖는 6벌의 데이터 베이스로 내구성이 매우 높다
  • Aurora Serverless 서비스가 새로 런칭, 필요할 때만 사용하고 사용하지 않을 때는 Shutdown되는 초당 과금 서비스

Amazon Redshift 서비스

  • 빠르고 강력한 페타 바이트 규모의 데이터 웨어하우스
  • 2PB까지 데이터 확장 가능(SSD 및 SAS 디스크 옵션 존재)

Amazon Dynamo DB 서비스

  • 완전관리형 key-value, 문서 데이터베이스
  • 어떤 규모에서도 10밀리초 미만의 성능 제공
  • 내구성이 뛰어난 다중 리전, 다중 마스터 DB
  • 하루 10조 개 이상 요청 처리 가능

Amazon DocumentDB

  • JSON 데이터에 최적화된 완전관리형 문서 데이터베이스
  • MongoDB와 호환되어 기존 MongoDB 드라이버 사용 가능

Amazon ElastiCache

  • Redis, Memcached와 호환되는 인 메모리 DB

AWS Schema Conversion Tool

  • 기존 DB 스키마를 다른 DB 엔진 스키마로 변환하는 툴

오전 강의 : AWS Aurora 실습

열어보기
  1. CloudFormation Template을 사용해 실습환경 생성 (Stack 생성에 10~20분 정도 걸림)
  2. Stack이 생성되면 출력(Outputs)에 Key-Value가 표시됨
  3. Session Manager를 이용해 EC2 인스턴스에 접속
  4. 터미널에서 우분투 유저로 스위칭하기 sudo su -l ubuntu
  5. tail -n1 /debug.log로 인스턴스의 정상 기동 확인 * bootstrap complete, rebootin
  6. env |grep DB로 DBUSER, DBPASS, DBUS_SESSION_BUS_ADDRESS를 각각 확인
  7. mysql client를 사용해 aurora 인스턴스로 접속을 확인 clusterEndpoint는 2번에서 확인 가능
1
2
3
4
5
6
7
8
9
export DBURL=auroralab-mysql-cluster.cluster-cqxoqejlondh.ap-northeast-2.rds.amazonaws.com
mysql -h$DBURL -u$DBUSER -p"$DBPASS" -e"SELECT @@aurora_version;"

mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------+
| @@aurora_version |
+------------------+
| 2.09.1 |
+------------------+
  1. 스프링을 sudo apt-get install openjdk-11-jdk -y로 설치
  2. PetClinic을 사용하기 위해 클론 및 빌드
1
2
3
4
5
git clone https://github.com/kiwonyoon0701/spring-petclinic.git
wget https://shared-kiwony.s3.ap-northeast-2.amazonaws.com/m2.tar.Z
tar xvfz m2.tar.Z
cd spring-petclinic/
./mvnw package -Dmaven.test.skip=true
  1. EC2의 퍼블릭 IP를 curl -s ifconfig.me | awk ' { print $1 "\n" }'로 확인 11.java -jar target/*.jar로 어플리케이션 기동
  2. 퍼블릭 IP와 8080포트로 어플리케이션 접속

→ 이후 DB관련 작업 및 DB복제 등의 작업이 이어짐 (클론 후 이어지는 작업이므로 생략)

Comment and share

[AWS Builders 프로그램] 클라우드 기초교육 및 실습

  • 교육 일자 : 2021. 04. 20(화)
  • AWS에서는 컴퓨팅, 스토리지, 데이터베이스 및 여러 개발 관련 서비스들을 제공함
  • 이 강의에서는 AWS의 서비스를 훑어보고 AWS의 보안 모델 등에 대해 배움

오전 강의 : AWS 서비스 톺아보기

열어보기

1. Amazon EC2

  • 웹 호스팅, 인증 서비스 등을 지원
  • 컴퓨팅 자원을 탄력적으로 이용 가능 (Instance Stop을 통해 비용 절감 가능)
  • 다양한 AWS 내 다른 모듈들과 혼용 가능

2. Amazon EBS(Elastic Block Store)

  • 인스턴스용 영구 블록 스토리지로 복제를 통해 보호됨
  • 데이터 소실을 대비해 두 개 이상의 가용영역을 사용하는 것을 권장함

3. Amazon S3

  • One Drive, Dropbox와 유사한 서비스
  • 데이터는 버킷 내에 객체로 저장됨 (파일 시스템이 아님)
  • 무제한 스토리지(단일 객체는 5TB로 제한됨)
  • 객체에 대해 빠르고 내구성과 가용성이 높은 키 기반 액세스
  • CLI가 S3 API를 통해 RESTful 요청을 전송하면 S3 버킷이 객체를 반환
  • 백업 및 스토리지, 애플리케이션 및 미디어 호스팅, 소프트웨어 전송 등에 사용 가능
  • Glacier 클래스는 매우 저렴하게 데이터를 보관할 수 있고 장기 백업이 가능함 (보관용이기 때문에 읽기에는 비싼 요금이 듦)

아키텍처 구성 예시: EC2 웹 어플리케이션에 S3 버킷을 통해 정적 콘텐츠를, EBS 볼륨을 통해 파일을 저장하는 DB로 사용, EC2를 호스팅하는 인스턴스 스토어를 사용

4. Amazon VPC(Virtual Private Cloud)

  • 인스턴스 수준에서 작용하는 보안 그룹을 설정하여 인/아웃바운드 규칙을 따로 설정 가능
  • 보안 그룹은 화이트 리스트 방식으로 거부 규칙을 지정할 수는 없음
  • 기본 값으로 인바운드 허용 안 함 / 아웃바운드 허용을 가짐

5. AWS CloudWatch

  • AWS 리소스, 실행중인 어플리케이션등에서 지표등을 수집하거나 추적하며 사용자에게 알림을 전송할 수 있음

6. Amazon Relational DB service

  • 클라우드에서 RDBMS의 설정, 운영 및 확장을 손쉽게 해주는 DB 서비스
  • Amazon Aurora, PostgreSQL, MariaDB, ORACLE 등 6가지의 DB를 사용 가능

7. Amazon SNS(Simple Notification Service)

  • 분산/서버리스 어플리케이션을 위한 완전 관리형 게시/구독 메시징(푸쉬)

8. Amazon CloudFront

  • 빠르고 안전한 글로벌 콘텐츠 전송 네트워크(CDN)
  • 사용자가 요청한다면 엣지 로케이션으로 라우팅하고 캐시에 있다면 사용자에게 바로 반환, 없다면 S3 버킷에 원본 파일을 요청해 캐싱하고 사용자에게 반환

예시) 미디어 스트리밍 서비스

  • 인코딩된 비디오 수집 → 여러 형식의 비디오 코드 변환 → 카탈로그 비디오 메타 데이터 → 클라이언트로 비디오 스트리밍
  • AWS Lambda에 코드를 업로드 → 이벤트 소스에서 코드가 트리거되도록 설정 → 트리거된 경우에만 Lambda에서 코드 실행 → 사용한 컴퓨팅 시간에 대해서만 비용 지불

오전 강의 : AWS의 보안

열어보기

1. 클라우드 자체의 보안

  • 호스트, 네트워크, 소프트웨어, 시설
  • AWS 글로벌 인프라 보호는 최고 우선 순위
  • 타사 감사 보고서 제공

2. 클라우드 내부의 보안

  • 무엇을 저장해야하는가
  • 어떤 AWS 서비스를 사용해야 하는가
  • 어느 리전에 저장해야 하는가
  • 콘텐츠 형식과 구조는 어떻게 되는가
  • 누가 액세스 할 수 있는가

3. 인증 및 권한 관리

  • IAM(Identity and Access Management)를 통해 AWS 리소스에 대한 액세스를 안전하게 제어 (추가비용 없음)
  • IAM 사용자, 그룹, 역할을 나누어 적용할 수 있음
  • IAM 정책을 통해 IAM 사용자, 그룹 또는 역할이 AWS CLI나 S3 버킷에 접근하거나 조작할 수 있게 된다
  • AWS 계정 루트 사용자는 모든 AWS 서비스에 대한 완전한 액세스 권한을 가짐 → 루트 사용자 액세스 키를 삭제, IAM 사용자를 생성하여 관리자 액세스 권한을 부여하고 IAM 자격 증명을 사용하여 AWS와 상호작용하도록 권장됨

오전 강의 : AWS의 요금 정책

열어보기
  • 사용량에 따라 지불, 예약을 통한 비용 절감, 사용량이 많을수록 비용 절감
  • 온디맨드, NURI(No up-front), PURI(Partial up-front), AURI(All up-front)
  • 서비스마다 요금이 다름

EC2의 네 가지 구매 유형

  • 온디맨드 인스턴스 (시간/초당 청구, 단기)
  • 예약 인스턴스 (1~3년 약정 할인)
  • 스팟 인스턴스 (최대 90% 할인되는 예비 AWS 용량, 시작 및 종료 시간이 자유로은 애플리케이션)
  • 전용 호스트 (고객 전용 물리서버, 특정 규정 준수 요구사항이 있는 애플리케이션)

S3의 요금 모델

  • 사용된 스토리지 양
  • 리전
  • 스토리지 클래스
  • 요청 수 및 유형 (GET, PUT, COPY)
  • 리전 외부로 전송된 데이터의 양

Trusted Advisor

  • 비용 절감 및 성능 개선 가능

AWS Support

  • Basic, Developer, Business, Enterprise 클래스로 나뉘며 모든 사용자는 기본값으로 Basic에 해당됨

오후 강의 : AWS 실습

열어보기

실습 과정

  • 네트워크 구성
  • 웹 서버 생성
  • 로드 밸런서 구성
  • 모니터링 (옵션)
  • 오토 스케일링 (옵션)
  • 정적 웹 사이트 호스팅 (옵션)

AWS 시작하기

  • 10분 자습서로 AWS 빠르게 시작
  • AWS 프리 티어 (12개월 무료)

AWS 실습

  1. 네트워크 구성하기
  • VPC 콘솔에서 VPC 마법사 시작
  • 단일 퍼블릭 서브넷이 있는 VPC
  • 해당 서브넷에 대한 CIDR 블록을 지정
  • CIDR이란? 참고자료

CIDR(Classless Inter-Domain Routing)는 클래스 없는 도메인 간 라우팅 기법으로 1993년 도입되기 시작한 최신의 IP주소 할당 방법으로 CIDR는 기존의 IP 주소 할당 방식이었던 네트워크 클래스를 방법을 대체한 방식.
CIDR는 IP Address의 영역을 나눌 때 기존방식보다 유연하게 자신이 원하는 Network Address와 Host Address를 나눌 수 있다.

  • 서브넷 메뉴에서 서브넷 생성으로 추가 서브넷 생성 시작

  • VPC 아이디에서 방금 생성한 VPC를 선택(추가 서브넷이므로)

  • CIDR는 기존 서브넷의 IP와 앞자리 두 블럭(고정 범위의 네트워크 주소)이 같도록 하고 뒷 두 블럭(가변 범위의 호스트 주소)이 다르게 설정

  • VPC 라우팅 테이블을 통해 방금 생성한 VPC의 라우팅 테이블 ID와 동일하도록 설정

  1. 보안 그룹 생성하기
  • 보안 그룹 메뉴에서 보안 그룹 생성
  • 보안 그룹 이름과 설명을 작성하고 1번에서 생성한 VPC ID로 설정
  • 인바운드 규칙HTTP/SSH위치 무관(소스)으로 설정
  1. 웹 서버 생성하기
  • EC2 콘솔에서 인스턴스 시작으로 인스턴스를 생성
  • Amazon Machine Image(AMI) 선택에서 Amazon Linux 2 AMI를 선택
  • t2.micro(프리 티어 사용 가능)를 선택한 후, 다음: 인스턴스 세부 정보 구성 버튼을 클릭
  • 네트워크와 서브넷을 선택하고 퍼블릭 IP 자동 할당활성화로 설정
  • 고급 세부 정보에 #include https://s3.amazonaws.com/immersionday-labs/bootstrap.sh를 입력
  • 태그 추가까지 넘어가 키와 값을 입력
  • 보안 그룹 구성에서 기존 보안 그룹 선택을 통해 2번에서 만든 보안 그룹을 선택하고 검토 및 시작
  • 새 키 페어 생성을 선택하고 키 페어 이름을 입력한 후 키 페어 다운로드
  • 인스턴스 시작으로 인스턴스를 생성(인스턴스 연결로 연결하여 CLI를 볼 수 있음)
  1. AMI 생성하고 AMI 기반 인스턴스 생성하기
  • Amazon Machine Image(AMI)는 인스턴스를 시작하는데 필요한 정보를 제공
  • 인스턴스를 선택하고 우측 상단 작업 메뉴에서 이미지 및 템플릿이미지 생성
  • 이미지 생성 페이지에서 이미지 이름을 입력하고 우측 하단의 이미지 생성 버튼을 클릭
  • 왼쪽 AMI 메뉴에서 상태가 available인지 확인하고 시작하기
  • 단계 3에서 VPC 네트워크를 선택하고 추가 서브넷을 서브넷으로 설정 및 퍼블릭 IP 자동 할당을 활성화로 설정
  • 단계 5에서 태그를 추가하여 값을 입력하고 보안 그룹을 설정(3번의 보안 그룹 설정 과정과 동일)
  • 키 페어는 위에서 생성한 키 페어를 사용
  1. 로드밸런서(Elastic Load Balancing) 구성하기
  • 로드밸런서는 애플리케이션 트래픽을 EC2 인스턴스, 컨테이너, IP 주소, Lambda 함수, 가상 어플라이언스와 같은 여러 대상에 자동으로 분산시킴
  • 로드 밸런서 메뉴에서 Load Balancer 생성
  • Load Balancer 유형 선택에서 Application Load Balancer를 선택
  • 1단계에서는 로드 밸런서 이름과 ip 주소 유형으로 ipv4를 선택, 리스너로는 HTTP가 선택되었는지 확인
  • 가용 영역 파트에서 VPC를 선택하고 가용 영역을 체크하여 서브넷들을 선택
  • 단계 3 보안 그룹 구성에서 새 보안 그룹 생성 선택하고 이름과 설명을 작성한 후 HTTP 유형의 위치 무관(소스)를 선택
  • 단계 4 라우팅 구성에서 이름을 작성하고 인스턴스를 대상으로 하는 HTTP 프로토콜로 설정
  • 단계 5 대상 등록에서 두 개의 인스턴스를 선택하고 등록된 항목에 추가
  • 검토 및 생성
  • 보안 그룹 메뉴 → 인바운드 규칙 편집
  • 로드밸런서의 트래픽만 받을 수 있도록 소스 부분에서 사용자 지정 → 로드 밸런서 보안 그룹을 선택
  • 밑의 HTTP 규칙을 삭제
  • 로드밸런서가 active로 상태가 변하면 DNS로 접속 해 보기

Comment and share

Ⅰ. 요구사항 확인

Chapter 02 소프트웨어 개발방법론

(1) 현행 시스템 파악

  • 구성/기능/인터페이스 파악 → 아키텍처 및 소프트웨어 구성 파악 → 하드웨어 및 네트워크 구성 파악

    • 구성 현황 파악 : 주요 업무를 처리하는 기간 업무와 지원 업무로 구분하여 파악

    • 기능 현황 파악 : 단위 업무 시스템이 현재 제공하고 있는 기능을 파악

    • 인터페이스 파악 : 다른 시스템과 주고받는 데이터의 종류, 형식, 프로토콜, 연계유형, 주기를 파악

    • 아키텍쳐 파악 : 계층별 기술 스택을 최상위 수준에서 파악

    • 소프트웨어 파악 : 소프트웨어의 제품명, 용도, 라이선스 적용 방식 및 라이선스 수 파악

    • 하드웨어 파악 : 서버의 위치 및 사양, 수량, 이중화 구현 여부 등을 파악

    • 네트워크 파악 : 어떤 네트워크 장비를 사용하여 구성되어있는지 파악

(2) 소프트웨어 아키텍처

  • 소프트웨어 아키텍처 프레임워크 : 소프트웨어 집약적인 시스템에서 아키텍처가 표현해야 하는 내용 및 이들간의 관계를 제공하는 아키텍처 기술 표준

    • 아키텍처 명세서 : 이해관계자들의 관점에 맞추어 작성하며 개별 뷰, 뷰 개괄 문서, 인터페이스 명세 등이 있음
    • 이해관계자 : 시스템 개발과 관련도니 모든 사람과 조직
    • 관심사 : 사용자, 유지보수자, 개발자 입장으로 나뉨
    • 관점 : 개별 뷰를 개발할 때 토대가 되는 패턴이나 양식
    • 뷰 : 서로 관련 있는 관심사들의 집합이라는 관점에서 전체 시스템을 표현
    • 근거 : 아키텍처 결정 근거(회의나 보고 결과)
    • 목표 : 환경 안에서 한 명 이상의 이해관계자들이 의도하는 시스템의 목적, 사용, 운영 방법
    • 환경 : 시스템에 영향을 주는 요인
    • 시스템 : 각 앱의 서브 시스템, 시스템 집합, 제품군 등의 구현체
  • 소프트웨어 아키텍처 4+1 뷰

    • 고객의 요구사항을 정리해 놓은 시나리오를 4개의 관점에서 바라보는 소프트웨어적인 접근방법으로 주로 유스케이스를 사용한다
    • 논리 뷰, 구현 뷰, 프로세스 뷰, 배포 뷰(4) + 유스케이스 뷰(1) 로 구성된다
    • 계측화 패턴, 클라이언트-서버 패턴, 파이프-필터 패턴, 브로커 패턴, 모델-뷰-컨트롤러 등으로 나뉨
  • 소프트웨어 아키텍처 비용 평가 모델

    • 아키텍처 접근법이 품질 속성에 미치는 영향을 판단, 아키텍처의 적합성을 평가하는 모델로 SAAM, ATAM, CBAM, ADR, ARID 등의 모델이 있다
  • 디자인 패턴

    • 소프트웨어 설계에서 공통으로 발생하는 문제에 대해 자주 쓰이는 설계 방법을 정리한 패턴

    • 개발의 효율성, 유지보수성, 운용성이 높아지며 프로그램의 최적화에 도움이 된다

    • 패턴의 이름, 문제 및 배경, 솔루션, 사례, 결과, 샘플 코드 등으로 구성되어 있다

    • 디자인 패턴의 유형은 목적(생성, 구조, 행위) 과 범위(클래스, 객체)로 구성된다

    • 디자인 패턴의 종류
      생성 패턴

      • Builder : 복잡한 인스턴스를 조립하여 만드는 구조로 객체를 생성하는 방법(과정)과 객체를 구현(표현)하는 방법을 분리
      • Prototype : 처음부터 원형을 만들어놓고 복사 후 필요한 부분만 수정하여 사용하는 패턴
      • Factory Method : 상위 클래스의 인터페이스를 하위 클래스에서 인스턴스를 생성하도록 하는 방식
      • Abstract Factory : 제공된 API를 사용하여 생성된 클래스를 Concrete Product 클래스에서 구체적으로 구현하는 패턴
      • Singleton : 한 클래스에 한 객체만 존재하도록 제한하는 패턴

      구조 패턴

      • Bridge : 기능 계층과 구현 계층을 연계하고 구현부에서 추상화된 부분을 독립적으로 확장할 수 있는 디자인 패턴
      • Decorator : 기존에 구현된 클래스에 필요한 기능을 추가해 나가는 설계 패턴으로 유연하게 확장 가능한 패턴
      • Facade : 단순한 인터페이스를 사용해 결합도를 낮추고 시스템 구조 파악을 쉽게 하는 패턴
      • Flyweight : 클래스의 경량화를 목적으로 하는 디자인 패턴
      • Proxy : 대리 객체를 사용해 메모리 용량을 절약하고 정보 은닉의 역할도 수행하는 디자인 패턴
      • Composite : 객체들을 트리 구조로 구성하여 복합 객체와 단일 객체를 모두 동일하게 다루도록 하는 패턴
      • Adapter : 상속을 이용하는 클래스 패턴과 위임을 이용하는 인스턴스 패턴의 두 가지 형태로 사용되는 디자인 패턴

      행위 패턴

      • Mediator : 객체지향 설계에서 중재자를 두고 통신의 빈도수를 줄여 객체 지향의 목표를 달성하게 해 주는 디자인 패턴
      • Interpreter : 언어의 구문을 나누어 해석을 맡는 클래스를 각각 작성하여 여러 형태의 언어 구문을 해석할 수 있게 만드는 디자인 패턴
      • Iterator : 내부 구조를 노출하지 않고 복잡한 객체의 원소를 순차적으로 순회 접근 가능하게 해주는 행위 패턴
      • Template Method : 상위 클래스에선 추상 메서드로 기능의 골격을, 하위 클래스에선 세부 처리를 구체화 하는 방식의 디자인 패턴
      • Observer : 객체의 상태 변화에 따라 다른 객체의 상태도 연동되는 일대다 의존 디자인 패턴
      • State : 객체 상태를 캡슐화하여 클래스화하여 참조케 하는 방식의 디자인 패턴
      • Visitor : 각 클래스 데이터 구조에서 처리기능을 분리, 별도의 클래스를 만들어놓고 해당 클래스의 메서드가 각 클래스를 돌아다니며 특정 작업을 수행하도록 만드는 패턴
      • Command : 재사용성이 높은 클래스를 설계하는 패턴으로 하나의 추상 클래스에 메서드를 만들어 각 명령이 들어오면 각 명령이 들어오면 그에 맞는 서브 클래스가 선택되어 실행되는 디자인 패턴
      • Strategy : 알고리즘을 하나의 클래스로 캡슐화하고 필요할 때서로 교환해서 사용할 수 있게 하는 패턴
      • Memento : 객체의 정보를 저장할 필요가 있을 때 적용하는 디자인 패턴으로 ‘작업취소(Undo)’를 요청 할 수 있다
      • Chain of Responsibility : 한 요청을 2개 이상의 객체에서 처리하도록 하는 디자인 패턴

(3) 현행 시스템 분석서 작성 및 검토

  • 현행 시스템 관련 자료 수집 → 수집 자료의 분석 → 분석한 결과를 기반으로 산출물 작성 → 산출물에 대한 검토 수행

(4) 개발 기술 환경 정의

  • 운영체제 시스템 분석
  • 네트워크 시스템 분석
    • OSI 7계층(응용, 표현, 세션, 전송, 네트워크, 데이터 링크, 물리 계층)
  • DBMS 시스템 분석
  • 미들웨어 시스템 분석
  • 오픈소스 사용 시 고려 사항
    • 라이선의 종류, 사용자 수, 기술의 지속 가능성 등을 고려

기출문제

  1. 다음 보기가 설명하는 패턴을 쓰시오
1
2
3
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에 연락이 가고
자동으로 내용이 갱신되는 방법으로 일대다의 의존성을 가지며
상호작용하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

Observer Pattern

  1. Linux 운영체제 위에서 구동하며 휴대폰 전화를 비롯한 휴대용 장치를 위한 운영체제와 미들웨어, 사용자 인터페이스 그리고 표준 응용 프로그램(웹 브라우저, 이메일 클라이언트, 단문 세시지 서비스, MMS) 등을 포함하고 있는 소프트웨어 스택이자 리눅스 모바일 운영체제로 개발자들이 자바와 코틀린 언어로 응용 프로그램을 작성할 수 있게 했고, 컴파일된 바이트 코드를 구동할 수 있는 런타임 라이브러리를 제공하는 운영체제는 무엇인지 쓰시오.

안드로이드

  1. 목적에 다른 디자인 패턴의 유형에는 생성, 구조, ( )이/가 있다. 괄호 안에 알맞는 유형을 쓰시오.

행위

예상문제

  1. 소프트웨어 아키텍처에 대해서 서술하시오.

여러 가지 소프트웨어 구성요소와 그 구성요소가 가진 특성 중에서 외부에 드러나는 특성, 그리고 구성요소 간의 관계를 표현하는 시스템의 구조나 구조체

  1. 4+1 뷰 중 다음 설명에 해당하는 뷰가 무엇인지 쓰시오.
1
2
3
- 시스템의 비기능적인 속성으로서 자원의 효율적인 사용, 병행 실행, 비동기,
이벤트 처리 등을 표현한 뷰
- 개발자, 시스템 통합자 관점

프로세스 뷰

  1. 시스템을 계층으로 구분하여 구성하는 패턴으로 서로 마주 보는 두 개의 계층 사이에서만 상호작용이 이루어지는 패턴은 무엇인가?

계층화 패턴

  1. MVC 패턴에 대해 서술하시오.

대화형 애플리케이션을 모델, 뷰, 컨트롤러 3개의 서브 시스템으로 구조화하는 패턴

  1. 디자인 패턴에 대해서 서술하시오.

소프트웨어 공학의 소프트웨어 설계에서 공통으로 발생하는 문제에 대해 자주 쓰이는 설계방법을 정리한 패턴

  1. 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하고, 한 클래스에 한 객체만 존재하도록 제한하는 디자인 패턴은 무엇인가?

싱글톤 패턴

  1. 상위 클래스에서 객체를 생성하는 인터페이스를 정의하고, 하위 클래스에서 인스턴스를 생성하도록 하는 방식으로, 상위 클래스에서는 인스턴스를 만드는 방법만 결정하고, 하위 클래스에서 그 데이터의 생성을 책임지고 조작하는 함수들을 오버로딩하여 인터페이스와 실제 객체를 생성하는 클래스를 분리할 수 있는 특성을 갖는 디자인 패턴은 무엇인가?

팩토리 메서드 패턴

  1. 알고리즘 군을 정의하고 같은 알고리즘을 각각 하나의 클래스로 캡슐화한 다음, 필요할 때 서로 교환해서 사용할 수 있게 하는 패턴으로, 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 디자인 패턴은 무엇인가?

전략 패턴

  1. 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴으로 일반적으로 상위 클래스(추상 클래스)에는 추상 메서드를 통해 기능의 골격을 제공하고, 하위 클래스(구체 클래스) 메서드에는 세부 처리를 구체화하는 방식으로 사용하며 코드 양을 줄이고 유지보수를 용이하게 만드는 특징을 갖는 디자인 패턴은 무엇인가?

템플릿 패턴

Comment and share

Ⅰ. 요구사항 확인

Chapter 01 소프트웨어 개발방법론

(1) 소프트웨어 생명주기 모델

  • 요구사항 분석 → 설계 → 구현 → 테스트 → 유지보수
  • 폭포수 모델(순차적), 프로토타이핑 모델(프로토타입), 나선형 모델(절차 반복적), 반복적 모델(병행적) 등이 있음

(2) 개발방법론

  • 구조적 방법론 : 기능에 따라 나누어 개발하고 통합하는 분할정복식 접근방법

  • 정보공학 방법론 : 개발주기를 이용해 대형 프로젝트를 수행하는 방법

  • 객체지향 방법론 : ‘객체’ 단위로 시스템을 분석 및 설계

  • 컴포넌트 기반 방법론 : 소프트웨어를 구성하는 컴포넌트를 조립해서 하나의 응용 프로그램을 작성하는 방법으로 확장성이 용이하며 소프트웨어의 재사용이 가능

  • 애자일 방법론 : 절차보다는 사람이 중심이 되어 변화에 유연하고 신속하게 적응하면서 효율적으로 시스템을 개발할 수 있는 경량 개발방법론으로 이터레이션 주기(분석→디자인→개발→테스트를 반복)를 통해 개발됨

    • 대표적인 애자일 방법론의 유형 : XP, Lean, 스크럼 등
  • XP(eXtreme Programming) : 용기, 단순성, 의사소통, 피드백, 존중의 5가지 가치를 가지며 짝프로그래밍을 포함한 12가지 기본 원리로 구성됨

  • 스크럼 : 매일 정해진 시간·장소에서 개발팀을 위한 프로젝트 관리 중심 방법론

    • 백로그, 스프린트, 스크럼 미팅, 스크럼 마스터, 스프린트 회고, 번 다운 차트
  • Lean : Just In Time, 칸반 보드를 사용함

(3) 비용산정, 일정관리 모형

  • 하향식, 상향식 산정방법
  • Lines of Code(LoC) 모형 : 낙관치, 중간치, 비관치를 측정하여 비용을 산정
  • Man Month 모형 : LoC / 프로그래머의 월간 생산성, Man Month / 프로젝트 인력 = 프로젝트 기간
  • COCOMO 모형
    • 조직형 : 5만라인 이하의 소프트웨어 개발에 적용
    • 반 분리형 : 30만라인 이하의 소프트웨어 개발에 적용
    • 임베디드형 : 30만라인 이상의 소프트웨어 개발에 적용
  • 푸트남 모형 : 단계별로 요구할 인력의 분포를 가정
  • 기능점수 모형 : 요인별 가중치를 합산하고 총 기능의 점수를 계산하여 비용을 산정 (기능점수 = 총 기능점수 x (0.65 + (0.1 총 영향도)))
  • 일정관리 모델에는 주 공정법, PERT, 중요 연쇄 프로젝트 관리가 있다

기출문제

  1. 절차보다는 사람이 중심이 되어 변화에 유연하고 신속하게 적응하면서 효율적으로 시스템을 갭라할 수 있는 신속 적응적 경량 개발방법론으로, 개발 기간이 짧고 신속하며, 워터폴에 대비되는 방법론으로 최근 회사에서 각광받는 방법론은 무엇인가?

애자일 방법론

  1. LoC가 30,000 라인이고 개발자가 5명이며, 월평균 300라인을 개발한다면 프로젝트 개발 기간과 계산식을 쓰시오

프로젝트 개발 기간 : Man Month = LoC / 월간 생산성 = 30,000 / 300 = 100개월
프로젝트 기간 = 100 개월 / 5 명 = 20개월

예상문제

  1. 소프트웨어 생명주기 모델에 대해 서술하시오

시스템의 요구분석부터 유지보수까지 전 공정을 체계화한 절차로 시스템이 개발될 때부터 운용과 유지보수를 거쳐 생애를 마칠 때 까지의 작업 프로세스를 모델화 한 것

  1. 소프트웨어 생명주기 모델 중에서 시스템 명세 단계에서 정의한 기능을 실제 수행할 수 있도록 수행 방법을 논리적으로 결정하는 단계는 무엇인가?

설계 단계

  1. 소프트웨어 개발 시 각 단계를 확실히 마무리 지은 후에 다음 단계로 넘어가는 모델은 무엇인가?

폭포수 모델

  1. 전체 시스템을 기능에 따라 나누어 개발하고 이를 통합하는 분할과 정복 접근 방식의 방법론은 무엇인가?

구조적 방법론

  1. TDD에 대해서 설명하시오

테스트를 기반으로 한 개발 방식으로 작성해야 하는 프로그램에 대한 테스트를 먼저 수행하고 이 테스트를 통과할 수 있도록 코드를 작성하는 것

  1. XP 12가지 가치 중 매일 여러 번씩 소프트웨어를 통합하고 빌드해야 한다는 원리는 무엇인가?

지속적인 통합

  1. 애자일 방법론 중에서 매일 정해진 시간, 장소에서 짧은 시간의 개발을 하는 팀을 위한 프로젝트 관리 중심 방법론은 무엇인가?

스크럼 기법

  1. 델파이 기법에 대해 서술하시오

전문가의 경험적 지식을 통한 문제 해결 및 미래 예측을 위한 기법

  1. 요구 기능을 증가시키는 인자별로 가중치를 부여하고 요인별 가중치를 합산하여 총 기능 점수를 계산하고 비용을 산정하는 방식은 무엇인가?

기능 점수 방식

  1. 일의 순서를 계획적으로 정리하기 위한 수렴 기법으로 비관치, 중간치, 낙관치의 3점 추정방식을 통해 일정을 관리하는 기법은 무엇인가?

PERT

  1. CPM 네트워크가 다음과 같을 때 임계 경로의 소요기일은 얼마인가?

14일

  1. LoC가 50,000라인, 개발자 10명, 월평균 250라인을 개발한다면 Man Month는 얼마인가?

50,000 / 250 = 200

Comment and share

5장 연습문제 다시 보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const findSumBetter = (arr, weight) => {
let hashtable = {};
for (let i = 0, arrLength = arr.length; i < arrLength; i++) {
let currentElement = arr[i];
let difference = weight - currentElement;

if (hashtable[currentElement] != undefined) {
return [i, hashTable[currentElement]];
} else {
hashtable[difference] = i;
}
}
return -1;
};

Comment and share

스킬트리

해당 문제 링크

  • 처음엔 각 스킬을 키로, 인덱스를 값으로 갖는 객체를 만들어 풀려 했으나 스킬트리 내 스킬들 인덱스 비교가 어려워서 다른 방법을 찾다가 정규식으로 처리하는 방법을 찾음
1
2
3
4
5
6
7
function solution(skill, skill_trees) {
let regex = new RegExp(`[^${skill}]`, 'g'); // 정규식으로 skill에 해당하지 않는(^) 글자를 찾게끔하기
let isPossible = skill_trees.map(eachTree => eachTree.replace(regex, '')) // replace를 통해 스킬이 아닌것들을 죄다 빈 문자열로 변환
.filter(each => skill.substring(0, each.length) === each)
// 정규식으로 필터링된 각 스킬트리를 substring으로 원래 스킬을 필터링된 문자열의 길이만큼 잘라내고 그 값이 스킬트리와 같은지 비교
return isPossible.length; // isPossible 배열 내에는 배울 수 있는 스킬만 남을 것이므로 배열의 길이를 리턴
}

괄호 변환

해당 문제 링크

1
2
3
4
5
6
7
8
9
10
1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다. 
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
4-3. ')'를 다시 붙입니다.
4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
4-5. 생성된 문자열을 반환합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function solution(p) {
if (p === '') return p; // 1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.

let left = 0, right = 0, pIndex = 0; // 레벨 1의 올바른 괄호처럼 left와 right를 나누기
let isBalanced = true; // "균형잡힌 괄호 문자열"의 flag 변수

do {
if (p[pIndex] === '(') left++;
else right++;

if(right > left)
isBalanced = false;
pIndex++;
} while (left !== right)

let u = p.substr(0, pIndex);
let v = p.substr(pIndex);

if(isBalanced) {
return u + solution(v);
} else {
u = u.substr(1, u.length - 2).replace(/[\(]|[\)]/g, a => a === ')' ? '(' : ')');
v = `(${solution(v)})`;
return v +u;
}
}
  • 재귀적으로 구현하는 법에 대해서 완벽하게 이해하지 못해서 다른 사람 풀이를 참고함
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function solution(p) {
    if (p.length < 1) return ""; // 1번

    let balance = 0; // 재귀적으로 호출될 때마다 0으로 초기화됨
    let pivot = 0;
    do {
    balance += p[pivot++] === "(" ? 1 : -1 // 좌측 괄호라면 1을 아니라면 -1을 더함
    } while (balance !== 0); // 0이라면 "균형잡힌 괄호 문자열"

    const u = p.slice(0, pivot); // balance가 0이 아니라면 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리
    const v = solution(p.slice(pivot, p.length)); // v는 1부터 다시 수행해야 하므로 재귀적으로 함수를 호출 (u로 나눠진 부분 다음부터)

    if (u[0] === "(" && u[u.length - 1] == ")") // 첫 괄호와 마지막 괄호를 검사해 "올바른 괄호 문자열"인지 확인
    return u + v;
    else
    return "(" + v + ")" + reverse(u);
    }

    function reverse(str) {
    return str.slice(1, str.length - 1) // u의 첫 번째와 마지막 문자를 제거
    .split("")
    .map((c) => (c === "(" ? ")" : "(")) // 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙임
    .join(""); // 다시 문자열로 join하여 리턴
    }

    소수 찾기(레벨2)

    해당 문제 링크
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    function solution(numbers) {
    let answer = 0;
    let primeNums = [];

    let splitedNumbers = numbers.split('')

    const isPrime = num => {
    let count = 0;
    for(let i = 1; i <= num; i++) {
    if (num % i === 0) {
    count++;
    }
    if (count >= 3) {
    break;
    }
    }
    if (count === 2 && !primeNums.includes(num)) {
    primeNums.push(num);
    }
    }

    const createNumbers = (arr, str) => {
    if (arr.length > 0) {
    for (let i = 0; i < arr.length; i++) {
    const temp = [...arr];
    temp.splice(i, 1);
    createNumbers(temp, str + arr[i])
    }
    }

    if (str.length > 0) {
    isPrime(+str);
    }
    }

    createNumbers(splitedNumbers, '');

    answer = primeNums.length;
    return answer;
    }

Comment and share

소수 만들기

해당 문제 링크

  • 에라토스테네스의 체를 세 정수의 최대값인 2997까지 구함
  • nums 배열을 돌며 세 정수의 합을 구해 배열에 push
  • 해당 배열 값을 인덱스로 가지는 에라토스테네스의 체의 값이 false가 아니라면 answer값을 증가시킨다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function solution(nums) {
let combination = [];
let answer = 0;
let primeNums = [];

for(let i = 2; i <= 2997; i++){
if(primeNums[i] == false)
continue;
for(let k = i + i; k <= 2997; k += i) {
primeNums[k] = false;
}
}


for (let i = 0; i < nums.length; i++) {
for (let j = i+1; j < nums.length; j++) {
for (let k = j+1; k < nums.length; k++){
let temp = nums[i]+nums[j]+nums[k];
combination.push(temp);
}
}
}

for (let i = 0; i < combination.length; i++) {
if(primeNums[combination[i]] !== false)
answer++
}
return answer;
}

신규 아이디 추천

해당 문제 링크

1
2
3
4
5
6
7
8
1. 모든 대문자를 대응되는 소문자로 치환합니다.
2. 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3. 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4. 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5. 빈 문자열이라면, "a"를 대입합니다.
6. 길이가 16자 이상이면, 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
7. 만약 제거 후 마침표(.)가 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
8. 길이가 2자 이하라면, 마지막 문자를 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
  • 정규식을 사용해 1번부터 8번을 구현하기
  • 4번, 5번을 모르겠어서 다른 분의 풀이를 참고함
  • 정규식은 언제 봐도 어렵다…
1
2
3
4
5
6
7
8
9
10
11
function solution(new_id) {
const answer = new_id
.toLowerCase() // 1. 모두 소문자로 치환
.replace(/[^\w-_.]/g, '') // 2. \w는 밑줄 문자를 포함한 영숫자 문자에 대응
.replace(/\.{2,}/g, '.') // 3. \.{2,}로 2개 이상 연속된다면 '.'로 replace
.replace(/^\.|\.$/g, '') // 4. 마침표가 처음과 끝에 있는지 확인 ^\.| \.$(^: 입력의 시작부분, $: 입력의 끝부분)
.replace(/^$/, 'a') // 5. 시작(^)과 끝($)이 빈 문자열이라면 a로 replace
.slice(0, 15).replace(/\.$/, ''); // 6, 7. slice로 15개 문자만 남기고 4번과 마찬가지로 \.$를 사용해 끝문자열의 마침표 삭제
const len = answer.length;
return len > 2 ? answer : answer + answer.charAt(len - 1).repeat(3 - len); // 8. 길이가 2보다 작다면 아이디 끝에 반복해서 붙이기
}

키패드 누르기

해당 문제 링크

1
2
3
4
5
6
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
  • 간단한 해시 테이블을 사용하여 키의 위치를 할당하고 번호마다 왼손, 오른손의 현재 위치와의 거리를 구하여 이동하게 함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function solution (numbers, hand) {
let answer = '';
let keypad = {
1: [1,1], 2: [1,2], 3: [1,3],
4: [2,1], 5: [2,2], 6: [2,3],
7: [3,1], 8: [3,2], 9: [3,3],
'*': [4,1], 0: [4,2], '#': [4,3],
}
let curLeft = keypad['*']
let curRight = keypad['#']
numbers.forEach(num => {
let numPosition = keypad[num];

if (numPosition[1] === 1) {
curLeft = numPosition
answer += 'L'
} else if (numPosition[1] === 3) {
curRight = numPosition
answer += 'R'
} else {
let distanceLeft = calDistance(curLeft, numPosition)
let distanceRight = calDistance(curRight, numPosition)

if(distanceLeft === distanceRight) {
if(hand === 'left') {
curLeft = numPosition;
answer += 'L'
} else {
curRight = numPosition;
answer += 'R'
}
} else if (distanceLeft < distanceRight) {
curLeft = numPosition;
answer += 'L';
} else {
curRight = numPosition;
answer += 'R';
}
}
})

return answer;
}

function calDistance(LeftOrRight, numPosition) {
return Math.abs(LeftOrRight[0] - numPosition[0]) + Math.abs(LeftOrRight[1] - numPosition[1])
}

하샤드 수

해당 문제 링크

  • 1분컷함…
    1
    2
    3
    4
    function solution(x) {
    let sum = (''+x).split('').map(el => el*1).reduce((acc, cur) => acc+cur, 0);
    return x%sum === 0;
    }

Comment and share

Harry Kim

author.bio


author.job