'분류 전체보기'에 해당되는 글 139건

  1. 2021.03.21 객체 지향 설계의 다섯가지 원칙
  2. 2021.03.21 var let const
  3. 2021.03.20 타일 깔기
  4. 2021.03.20 javascript 2차원배열의 얕은 복사
  5. 2021.03.19 Terminal 명령어 모음
  6. 2021.03.19 Git 사용하기
  7. 2021.03.19 Node 명령어
  8. 2021.03.19 HTTP CORS 여러개의 origin 관리하기

객체 지향 설계의 다섯가지 원칙

웹 개발/Study 2021. 3. 21. 17:08

컴퓨터 프로그래밍에서 SOLID란 로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 마이클 페더스가 두문자어 기억술로 소개한 것이다. 프로그래머가 시간이 지나도 유지보수와 확장이 쉬운 시스템을 만드록자 할 때 이 원칙들을 함께 적용 할 수 있다. SOLID원칙들은 소프트웨어 작업에서 프로그래머가 소스코드가 읽기 쉽고 확장하기 쉽게 될 때까지 소프트웨어 소스코드를 리팩터링하여 코드냄새를 제거하기 위해 적용할 수 있는 지침이다. 이 원칙들은 애자일 소프트웨어 개발과 적응적 소프트웨어 개발의 전반적 전략의 일부다. 

두문자약어개념SOLID

두문자 약어 개념
S SRP 단일 책임 원칙 (Single responsibility principle) 클래스는 하나의 책임만 가져야 한다.
O OCP 개방-폐쇄 원칙 (Open/closed principle)“소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.”
L LSP 리스코프 치환 원칙 (Liskov substitution principle)“프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.” 계약에 의한 설계를 참고하라.
I ISP 인터페이스 분리 원칙 (Interface segregation principle)“특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.”[4]
D DIP 의존관계 역전 원칙 (Dependency inversion principle)프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”[4] 의존성 주입은 이 원칙을 따르는 방법 중 하나다.

 

'웹 개발 > Study' 카테고리의 다른 글

웹팩 dependencies 설정  (0) 2021.08.20
React 기초 연습  (0) 2021.03.25
var let const  (0) 2021.03.21
Git 사용하기  (0) 2021.03.19
Node 명령어  (0) 2021.03.19
:

var let const

웹 개발/Study 2021. 3. 21. 17:03

var, let, const의 차이점

1. var는 함수 레벨 스코프이고 let, const는 블럭 레벨 스코프입니다.

2. var로 선언한 변수는 선언 전에 사용해도 에러가 나지 않지만 let, const는 에러가 발생합니다.

3. var는 이미 선언되어있는 이름과 같은 이름으로 변수를 또 선언해도 에러가 나지 않지만 let, const는 이미 존재하는 변수와 같은 이름의 변수를 또 선언하면 에러가 납니다.

4. var, let은 변수 선언시 초기 값을 주지 않아도 되지만 const는 반드시 초기값을 할당해야 합니다.

5. var, let은 값을 다시 할당할 수 있지만 const는 한번 할당한 값은 변경할 수 없습니다(단, 객체 안에 프로퍼티가 변경되는 것까지 막지는 못합니다).

함수레벨 스코프란?

// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 된다.
// 이건 var가 hoisting이 되었기 때문이다.
for(var j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10


// 아래의 경우에는 에러가 발생한다.
function counter () {
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined

 

'웹 개발 > Study' 카테고리의 다른 글

React 기초 연습  (0) 2021.03.25
객체 지향 설계의 다섯가지 원칙  (0) 2021.03.21
Git 사용하기  (0) 2021.03.19
Node 명령어  (0) 2021.03.19
HTTP 상태 코드/ 요청 메서드  (0) 2021.03.19
:

타일 깔기

웹 개발/Algorithm 2021. 3. 20. 16:38
더보기

문제

세로 길이 2, 가로 길이 n인 2 x n 보드가 있습니다. 2 x 1 크기의 타일을 가지고 이 보드를 채우는 모든 경우의 수를 리턴해야 합니다.

입력

인자 1 : n

  • number 타입의 1 이상의 자연수

출력

  • number 타입을 리턴해야 합니다.

주의사항

  • 타일을 가로, 세로 어느 방향으로 놓아도 상관없습니다. (입출력 예시 참고)

입출력 예시

let output = tiling(2);
console.log(output); // --> 2

output = tiling(4);
console.log(output); // --> 5
/* 
2 x 4 보드에 타일을 놓는 방법은 5가지
각 타일을 a, b, c, d로 구분

2 | a b c d
1 | a b c d 
------------

2 | a a c c
1 | b b d d 
------------

2 | a b c c
1 | a b d d 
------------

2 | a a c d
1 | b b c d 
------------

2 | a b b d
1 | a c c d 
------------
*/

Advanced

  • 타일링 문제를 해결하는 효율적인 알고리즘(O(N))이 존재합니다. 반드시 직접 문제를 해결하시면서 입력의 크기에 따라 어떻게 달라지는지 혹은 어떻게 반복되는지 관찰하시기 바랍니다.

 

답안1(시간복잡도 계산 x, 무식하게 하나씩 둬보기!):

더보기
let tiling = function (n) {
	// TODO: 여기에 코드를 작성합니다.
	let count = 0;
	let ground = [];
	for (let i = 0; i < 2; i++) {
		//세로길이 2
		ground.push(new Array(n).fill(0));
	}
	//[0, 0, 0, 0, 0]
	//[0, 0, 0, 0, 0]
	//{1: [[0,0],[1,0]]} 1번 타일
	//{2: [[0,1],[1,1]]} or {2: [[0,1],[0,2]]} 2번 타일
	let find0 = function (changedField) {
		for (let i = 0; i < changedField.length; i++) {
			for (let j = 0; j < changedField[i].length; j++) {
				if (changedField[i][j] === 0) {
					return [i, j];
				}
			}
			//다 채워지면
		}
		return null;
	};
	//startIndex = find0(field)
	let putTile = function (field) {
		//가로로 넣어보기 --> x축에 +1
		if (find0(field) === null) {//필드가 다 채워지면			
			count++;
		} else {
			let [y, x] = find0(field);
			//세로로 넣어보기
			if (field[y + 1] !== undefined) {
				if (field[y + 1][x] === 0) {
					//세로로 놓아지는지 확인
					//let copyfield = field.slice();
					let copyfield = [];
					for (let row of field) {//2차원 배열을 복사할땐 이렇게 해야한다!!
						copyfield.push(row.slice());
					}
					copyfield[y][x] = 1;
					copyfield[y + 1][x] = 1;					
					putTile(copyfield);				
				}
			}
			if (field[y][x + 1] === 0) {
				//가로로 놓아지는지 확인
				let copyfield = [];
				for (let row of field) {
					copyfield.push(row.slice());
				}
				copyfield[y][x] = 1;
				copyfield[y][x + 1] = 1;
				putTile(copyfield); // 다음 타일 놓기
			}

			//넣고 재귀 돌리기
			//다 채워지면 count++
		}
	};
	putTile(ground);
	return count;
};

 

답안2(시간복잡도 계산. O(n)):

더보기
// naive solution: O(2^N)
// 2 x 4 보드에 타일을 놓는 방법은 5가지다.
// 각 타일을 a, b, c, d로 구분한다.
// 아직 타일이 놓이지 않는 부분은 -로 표기한다.
// 타일을 놓는 방법은 가장 왼쪽부터 세로로 놓거나 가로로 놓는 것으로 시작한다.
// 1) 세로로 놓는 법
//   2 | a - - -
//   1 | a - - -
//   ------------
// 2) 가로로 놓는 법
// 타일을 가로로 놓게 되면, 그 바로 아래에는 가로로 놓을 수 밖에 없다.
//   2 | a a - -
//   1 | b b - -
//   ------------
// 이때, 타일이 아직 놓이지 않은 부분은 사실 크기만 다를뿐 같은 종류의 문제라는 것을 알 수 있다.
// 즉, 2 x 4 보드에 타일을 놓는 방법은 아래 두 가지 방법을 더한 결과와 같다.
//  1) 2 x 3 보드에 타일을 놓는 방법
//  2) 2 x 2 보드에 타일을 놓는 방법
// 따라서 2 x n 타일 문제는 아래와 같이 재귀적으로 정의할 수 있다.
// 주의: 재귀적 정의에는 항상 기초(base), 즉 더 이상 재귀적으로 정의할 수 없는(쪼갤 수 없는) 문제를 별도로 정의해야 한다.
// let tiling = function (n) {
//   if (n <= 2) return n;
//   return tiling(n - 1) + tiling(n - 2);
// };

// dynamic with memoization: O(N)
let tiling = function (n) {
  // 인덱스를 직관적으로 관리하기 위해
  // 앞 부분을 의미없는 데이터(dummy)로 채운다.
  const memo = [0, 1, 2];

  // 재귀를 위한 보조 함수(auxiliary function)을 선언)
  const aux = (size) => {
    // 이미 해결한 문제는 풀지 않는다.
    if (memo[size] !== undefined) return memo[size];
    if (size <= 2) return memo[n];
    memo[size] = aux(size - 1) + aux(size - 2);
    return memo[size];
  };
  return aux(n);
};

// dynamic with tabulation: O(N)
// tabulation은 데이터를 테이블에 정리하면서 bottom-up 방식으로 해결하는 기법을 말합니다.
// let tiling = function (n) {
//   const memo = [0, 1, 2];
//   if (n <= 2) return memo[n];
//   for (let size = 3; size <= n; size++) {
//     memo[size] = memo[size - 1] + memo[size - 2];
//   }
//   return memo[n];
// };

// dynamic with slicing window: O(N)
// slicing window은 필요한 최소한의 데이터만을 활용하는 것을 말합니다.
// 크기 n의 문제에 대한 해결을 위해 필요한 데이터는 오직 2개뿐이라는 사실을 이용합니다.
// let tiling = function (n) {
//   let fst = 1,
//     snd = 2;
//   if (n <= 2) return n;
//   for (let size = 3; size <= n; size++) {
//     // 앞의 두 수를 더해 다음 수를 구할 수 있다.
//     const next = fst + snd;
//     // 다음 문제로 넘어가기 위해 필요한 2개의 데이터의 순서를 정리한다.
//     fst = snd;
//     snd = next;
//   }
//   return snd;
// };

'웹 개발 > Algorithm' 카테고리의 다른 글

효율적인 피보나치  (0) 2021.03.15
집밥이 그리워  (0) 2021.03.11
빼빼로 데이(최대공약수)  (0) 2021.03.11
발표 순서  (0) 2021.03.11
금고를 털어라  (0) 2021.03.11
:

javascript 2차원배열의 얕은 복사

Ubuntu/삽질하기 2021. 3. 20. 16:13
let arr = [[1,2],[3,4]]
let arr2 = arr.slice()
arr2[0][0] = 5
//arr의 값은?

 

위의 문제에서 arr의 값은 아주 소름돋게도 [[5,2],[3,4]]가 된다.

arr.slice()함수가 원본배열을 그대로 복사해서 arr2에 넣어줘서 arr2의 값을 아무렇게나 바꿔줘도 원본 배열인 arr의 값은 안바뀔줄 알고 한참을 헤맸다... 그러다가 혹시나 하는 마음에 찍어 보니 원본배열을 바꾸고있었다!!! 

slice()함수가 배열안의 값을 하나씩 끄집어 내서 넣어주는 방식으로 복사가 이루어 지다보니 결국 arr2자체는 arr의 주소값을 참조하지 않지만 arr2의 요소 하나하나는 arr의 요소들의 주소값을 참조를 하고 있었던것이다.

따라서 for문을 이용해 복사를 해줘야한다... ㄷㄷ 소름

'Ubuntu > 삽질하기' 카테고리의 다른 글

MongoDB 실행 오류  (0) 2024.05.19
그래픽 드라이버 nouveau 에서 nvidia로 변경하기  (0) 2021.02.23
:

Terminal 명령어 모음

Ubuntu 2021. 3. 19. 18:46

sudo lspci -k

각종 사용 중 인 kernel driver확인

 

nvidia-smi

그래픽 카드 시스템 정보 확인

 

cat /proc/driver/nvidia/version

nvidia드라이버가 설치 되어있는지 확인

 

pwd

현재 위치 확인

 

절대경로:

절대경로란 최상위 디렉토리 (/)부터 시작해서 목표 디렉토리까지 가는 경로를 전부 기술하는 방식이다.

절대경로로 경로를 기술할 때에는 항상 맨 앞에 최상위 디렉토리 (/)가 붙는다는 것을 명심하자.

절대 경로는 어렵지 않다. 그냥 최상위부터 해당 디렉토리가 위치하는 곳 까지의 경로를 차례대로 적어주면 되기 때문이다.

 

상대경로:

상대경로는 '현재 자신이 있는 위치를 기준으로' 이동을 하는 것이다.

그리고 '현재 자신이 있는 위치'. 으로 표기한다.

 

cd ../

이전 디렉토리로 이동

 

cd ./디렉토리명

현재 위치에서 다음 디렉토리로 이동

더보기

리눅스 기본 명령어

명령어

사 용 법

login

사용자 인증과정

리눅스 시스템은 기본적으로 multi-user 개념에서 시작하였기 때문에 시스템을 이용하기 위해서는 반드시 로그인을 하여야 합니 다. 로그인은 PC 통신에서도 많이 사용되어져 왔기 때문에 그 개 념  설정에 그다지 어려움이 없을 것입니다. 흔히 말하는 ID를 입력하는 과정입니다. 

passwd

패스워드 변경

리눅스, 특히 인터넷의 세계에서는 일반 컴퓨팅 상황에 비하여 훨씬 해킹에 대한 위험이 높습니다. 패스워드는 완성된 단어 보다는 단어 중간에 숫자나 키보드의 ^, #, ' 등과 같은 쉽게 연상 할 수 없는 기호를 삽입하여 만들어 주는 것이 좋습니다

du

하드사용량 체크(chkdsk)

자신의 하드공간을 알려면
# du 
특정 디렉토리의 사용량을 알려면
# du -s diretory_name

ls

파일 리스트 보기(dir)

F : 파일 유형을 나타내는 기호를 파일명 끝에 표시
    (디렉토리는 '/', 실행파일은 '*', 심볼릭 링크는 '@'가 나타남).
l  : 파일에 관한 상세 정보를 나타냅니다.
a : dot 파일(.access 등)을 포함한 모든 파일 표시.
t  : 파일이 생성된 시간별로 표시
C : 도스의 dir/w명령과 같 이 한줄에 여러개의 정보를 표시
R : 도스의 dir/s 명령과 같이 서브디렉토리 내용까지.

(예)
# ls -al  
# ls -aC
# ls -R

cd

디렉토리를 변경

# cd cgi-bin     : 하부 디렉토리인 cgi-bin으로 들어감.
# cd  ..             : 상위디렉토리로 이동
# cd 또는 cd ~  : 어느곳에서든지 자기 홈디렉토리로 바로 이동
# cd /webker     : 현재 작업중인 디렉토리의 하위나 상위 디렉토리가
                          아닌 다른 디렉토리(webker)로 이동하려면 /로 
                          시작해서 경로이름을 입력하면 된다.

cp

화일 복사(copy)

# cp index.html index.old 
     : index.html 화일을 index.old 란 이름으로 복사.

# cp /home/test/*.*  . 
     : test 디렉토리내의 모든 화일을 현 디렉토리로 복사.

mv

파일이름(rename) / 위치(move)변경

# mv index.htm index.html
     : index.htm 화일을 index.html 로 이름 변경

$ mv file  ../main/new_file 
     : 파일의 위치변경

mkdir

디렉토리 생성

# mkdir download  : download 디렉토리 생성

rm

화일삭제

# rm test.html : test.html 화일 삭제
# rm -r <디렉토리> : 디렉토리 전체를 삭제
# rm -i a.* 
     : a로 시작하는 모든 파일을 일일이 삭제할 것인지 확인하면서 삭제 

rmdir

디렉토리 삭제

# rmdir cgi-bin : cgi-bin 디렉토리 삭제

pwd

현재의 디렉토리 경로를 보여주기

pico

리눅스용 에디터

put

ftp 상태에서 화일 업로드

> put  guestbook.tar.gz

get

ftp 상태에서 화일 다운로드

> get  guestbook.tar.gz

mput 또는 mget

여러개의 화일을 올리고 내릴때 (put,get과 사용법동일)

chmod

화일 permission 변경

리눅스에서는 각 화일과 디렉토리에 사용권한을 부여.

예) -rwxr-xr-x   guestbookt.html
rwx  :처음 3개 문자 = 사용자 자신의 사용 권한
r-x  :그다음 3개 문자 = 그룹 사용자의 사용 권한
r-x  :마지막 3개 문자 = 전체 사용자의 사용 권한

읽기(read)---------- 화일 읽기 권한
쓰기(write)---------- 화일 쓰기 권한
실행(execution)---------- 화일 실행 권한
없음(-)---------- 사용권한 없음

명령어 사용법
chmod [변경모드] [파일]

# chmod 666  guestbook.html
     : test.html 화일을 자신에게만 r,w,x 권한을 줌

# chmod 766  guestbook.html
     : 자신은 모든 권한을 그룹사용자와,전체사용자에게는 
       읽기와 쓰기 권한만 줌

alias

" doskey alias" 와 비슷하게 이용할 수 있는 쉘 명령어 alias는 말그대로 별명입니다. 사용자는 alias를 이용하여 긴 유 닉스 명령어를 간단하게 줄여서 사용할 수도 있습니다. 
이들 앨리어스는 [alias ls 'ls -al'] 같이 사용하시면 되는데, 한 번 지정한 alias를 계속해서 이용하시려면, 자신의 홈디렉토리에 있는 
.cshrc(Hidden 속성)을 pico등의 에디터를 이용하여 변경시 키면 됩니다.

cat

파일의 내용을 화면에 출력하거나 파일을 만드는 명령( 도스의 TYPE명령)

# cat filename

more

cat 명령어는 실행을 시키면 한 화면을 넘기는 파일일 경우 그 내용을 모두 볼수가 없다. 하지만 more 명령어를 사용하면 한 화면 단위로 보여줄 수 있어 유용.

# more <옵션>
옵션은 다음과 같습니다.

Space bar : 다음 페이지
Return(enter) key : 다음 줄
v : vi 편집기로 전환
/str : str 문자를 찾음
b : 이전 페이지
q : more 상태를 빠져나감
h : 도움말
= : 현재 line number를 보여줌

who

현재 시스템에 login 하고 있는 사용자의 리스트를 보여줍니다.

# who

whereis

소스, 실행파일, 메뉴얼 등의 위치를 알려줍니다

# whereis perl : perl의 위치를 알려준다

vi,
touch,
cat

새로운 파일을 만드는 방법

# vi newfile :  vi 편집기 상태로 들어감
# touch newfile : 빈 파일만 생성됨
# cat > newfile  : vi 편집기 상태로 들어감, 문서 작성후 Ctrl+D로 빠져나옴

cat,
head,
tail

파일 내용만 보기

# cat filename         : 파일의 내용을 모두 보여줌
# head -n filename : n줄 만큼 위세서부터 보여줌
# tail -n filename     : n줄 만큼 아래에서부터 보여줌



출처: https://lucas-look.tistory.com/40 [루카스의 봄]

 

:

Git 사용하기

웹 개발/Study 2021. 3. 19. 18:45

git remote add pair <Repo URL for pairs fork>

git remote -v

페어의 레버지토리 연결

 

git add<change file>

git commit -m “memo”

git push origin master ( or other branch name)

push는 자신의 레포지토리에다가 해야함

 

git pull pair master ( or other branch name)

pull은 항상 페어의 레포지토리에서 해야함

페어의 레포지토리에서 변경사항 가져오기

 

git add <change file>

git commit -m “change”

 

git pull pair master

 

 

git config credential.helper store

인증을 캐시에 저장하여 일정시간동안 입력하지 않는다.

 

git config –global credential.hgelper ‘cache –timeout 7200’

timeout뒤의 숫자는 초(second)이다. 여기서는 7200만큼(2시간)의 만료시간을 추가했다.

1day – 86400

7days – 604800

30days – 2592000

 

git checkout

branch 이동

 

git checkout -b 기능1

현재 작업공간을 베이스로 브랜치 생성

기능1 branch 생성 + 기능1 branch로 작업공간 이동

 

git branch

branch확인, q로 나가기

 

'웹 개발 > Study' 카테고리의 다른 글

객체 지향 설계의 다섯가지 원칙  (0) 2021.03.21
var let const  (0) 2021.03.21
Node 명령어  (0) 2021.03.19
HTTP 상태 코드/ 요청 메서드  (0) 2021.03.19
Promise 정리  (0) 2021.03.19
:

Node 명령어

웹 개발/Study 2021. 3. 19. 18:43

npm install

모듈 설치

 

안될 시

/bin/bash -c "$(curl -fsSL https://codestates-content.s3.ap-northeast-2.amazonaws.com/npm-registry/registry.sh)"

 

npx codestates-submission ls

나의 제출 확인

 

 

바뀐 쉘로 인해 nvm실행 안될 시

사용중인 쉘 파일에 추가:

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm



npm run submit

과제제출



npm init

npm 패키지를 활용하는 파일로 정의하겠다 → package.json파일 생성



package.json 에서 scripts 부분에 “start” : “node 파일명”을 입력해주면

npm start를 통해 해당 파일을 실행 할 수 있다.



npm install --save 패키지명

--save를 해줘야 package.json에 해당 dependency에 대한 정보가 추가됨.



npm install --save nodemon

파일을 저장할때마다 자동으로 파일을 실행시켜준다.



nodemon 사용법:

nodemon 파일명

nodemon 설정

이런식으로 추가 한 후 터미널에 npm run auto를 실행시키면 정상작동된다.

'웹 개발 > Study' 카테고리의 다른 글

var let const  (0) 2021.03.21
Git 사용하기  (0) 2021.03.19
HTTP 상태 코드/ 요청 메서드  (0) 2021.03.19
Promise 정리  (0) 2021.03.19
웹 아키텍쳐  (0) 2021.03.17
:

HTTP CORS 여러개의 origin 관리하기

웹 개발/Problems 2021. 3. 19. 18:19

'Access-Control-Allow-Origin'의 값은 기본적으로 한개의 origin을 입력받던가 모든 오리진을 허용해주는 '*'이라는 와일드카드를 값으로 받을 수 있다.

만약 여러개의 origin을 허용하고 싶다면 따로 배열을 만들고 들어온 request의 origin이 그 배열에 포함이 되있는지 확인 하는방법을 사용할 수 있다. 확인 후에 해당 origin을 현재 'Access-Control-Allow-Origin'의 값으로 넣어주면 된다.

const server = http.createServer((request, response) => {
	let body = [];
	let allowedOrigins = [
		//multiple origin 설정하기
		'http://127.0.0.1:5500',
		'http://14.36.99.81:44949',
		'http://14.36.99.81:35911',
	];
	let origin = request.headers.origin; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@origin 가져오기
	temp = request.headers;
	console.log(
		'defaultCorsHeader[Access-Control-Allow-Origin]: ',
		defaultCorsHeader['Access-Control-Allow-Origin'],
	);
	console.log('origin: ', origin);

	if (allowedOrigins.includes(origin)) {
		defaultCorsHeader['Access-Control-Allow-Origin'] = origin;
	}
}

 

: