Now Loading ...
-
-
dynamic programming
동적 계획법(Dynamic Programming)
WHAT IS?
하나의 큰 문제를 여러 개의 작은 문제로 나누어서 그 결과를 저장하여 다시 큰 문제를 해결할 때 사용하는 컨셉! 수열의 점화식 느낌 유남생? aka ‘기억하며 풀기’
WHY USE?
사실 DP는 일반적인 재귀법과 매우 유사함. 하지만 그 효율성은 말도 못하게 더 높다.
일반적인 재귀법은 보통 O(n^2)의 시간 복잡도를 나타내는 반면 DP는 O(f(n))의 시간 복잡도를 보인다.
위 그림처럼 재귀법을 사용한다면 불필요하게 한번 구했던 값 (=함수 호출 횟수)을 한번 더 구해야함.
이때 한번 구한 작은 문제의 결과 를 저장했다가 재사용 하면 굉장히 효율적이게 되겠죵?
이것이 바로 DP의 핵심 개념입니다!
WHAT CONDITIONS?
DP를 사용하기 위해서는 아래 2조건을 만족해야 합니다.
겹치는 부분 문제 (Overlapping Subproblems)
DP는 기본적으로 문제를 나누고 그 문제의 결과 값을 재활용해서 전체 답을 구한다. 그래서 동일한 작은 문제들이 반복하여 나타나는 경우에 사용이 가능하다.
즉, DP는 부분 문제의 결과를 저장하여 재 계산하지 않을 수 있어야 하는데, 해당 부분 문제가 반복적으로 나타나지 않는다면 재사용이 불가능하니 부분 문제가 중복되지 않는 경우에는 사용할 수 없다.
최적 부분 구조 (Optimal Substructure)
부분 문제의 최적 결과 값을 사용해 전체 문제의 최적 결과를 낼 수 있는 경우를 의미한다.
만약, A - B까지의 가장 짧은 경로를 찾고자 하는 경우를 예시로 할 때, 중간에 X가 있을 때, A - X / X - B가 많은 경로 중 가장 짧은 경로라면 전체 최적 경로도 A - X - B가 정답이 된다.
HOW USE?
아래 단계를 거쳐 문제를 해결할 수 있습니다.
DP로 풀 수 있는 문제인지 확인
문제의 변수 파악
변수 간 관계식 만들기(점화식)
메모하기(memoization or tabulation)
기저 상태 파악하기
구현하기
1. DP로 풀 수 있는 문제인지 확인
현재 직면한 문제가 작은 문제들로 이루어진 하나의 함수로 표현될 수 있는지를 판단
보통 특정 데이터 내 최대화 / 최소화 계산을 하거나 특정 조건 내 데이터를 세야 한다거나 확률 등의 계산의 경우 DP로 풀 수 있는 경우가 많다.
2. 문제의 변수 파악
문제 내 변수의 개수를 알아내야 한다. ( = state를 결정한다.)
예를 들어, 피보나치 수열에서는 n번째 숫자를 구하는 것이므로 n이 변수가 된다. 그 변수가 얼마이냐에 따라 결과값이 다르지만 그 결과를 재사용하고 있다.
3. 변수 간 관계식(점화식) 만들기
변수들에 의해 결과 값이 달라지지만 동일한 변수값인 경우 결과는 동일하므로 우리는 이를 관계식으로 만들어 낼 수 있고 그 관계식을 점화식이라고 한다!
예를 들어 피보나치 수열에서는 f(n) = f(n-1) + f(n-2)
4. 메모하기
변수 간 관계식까지 정상적으로 생성되었다면 변수의 값에 따른 결과를 저장
보통 배열을 쓰며 변수의 개수에 따라 배열의 차원이 1~3차원 등 다양할 수 있다.
5. 기저 상태 파악하기
가장 작은 문제의 상태를 알아야 한다.
피보나치 수열을 예시로 들면, f(0) = 0, f(1) = 1과 같은 방식
해당 기저 문제에 대해 파악 후 미리 배열 등에 저장해두면 된다.
6. 구현하기
2가지 방식으로 구현 가능함.
Bottom-Up (Tabulation 방식) - 반복문 사용
아래에서 부터 계산을 수행 하고 누적시켜서 전체 큰 문제를 해결하는 방식
dp[0]부터 시작하여 반복문을 통해 점화식으로 결과를 내서
dp[n]까지 그 값을 전이시켜 재활용하는 방식
메모하기 부분에서 Memoization이라고 했는데 Bottom-up일 때는 Tabulation이라고 부른다.
Top-Down (Memoization 방식) - 재귀 사용
dp[0]의 기저 상태에서 출발하는 대신 dp[n]의 값을 찾기 위해 위에서 부터 바로 호출을 시작하여 dp[0]의 상태까지 내려간 다음 해당 결과 값을 재귀를 통해 전이시켜 재활용하는 방식
packge com.test;
public class Fibonacci{
// DP 를 사용 시 작은 문제의 결과값을 저장하는 배열
// Top-down, Bottom-up 별개로 생성하였음(큰 의미는 없음)
static int[] topDown_memo;
static int[] bottomup_table;
public static void main(String[] args){
int n = 30;
topDown_memo = new int[n+1];
bottomup_table = new int[n+1];
long startTime = System.currentTimeMillis();
System.out.println(naiveRecursion(n));
long endTime = System.currentTimeMillis();
System.out.println("일반 재귀 소요 시간 : " + (endTime - startTime));
System.out.println();
startTime = System.currentTimeMillis();
System.out.println(topDown(n));
endTime = System.currentTimeMillis();
System.out.println("Top-Down DP 소요 시간 : " + (endTime - startTime));
System.out.println();
startTime = System.currentTimeMillis();
System.out.println(bottomUp(n));
endTime = System.currentTimeMillis();
System.out.println("Bottom-Up DP 소요 시간 : " + (endTime - startTime));
}
// 단순 재귀를 통해 Fibonacci를 구하는 경우
// 동일한 계산을 반복하여 비효율적으로 처리가 수행됨
public static int naiveRecursion(int n){
if(n <= 1){
return n;
}
return naiveRecursion(n-1) + naiveRecursion(n-2);
}
// DP Top-Down을 사용해 Fibonacci를 구하는 경우
public static int topDown(int n){
// 기저 상태 도달 시, 0, 1로 초기화
if(n < 2) return topDown_memo[n] = n;
// 메모에 계산된 값이 있으면 바로 반환!
if(topDown_memo[n] > 0) return topDown_memo[n];
// 재귀를 사용하고 있음!
topDown_memo[n] = topDown(n-1) + topDown(n-2);
return topDown_memo[n];
}
// DP Bottom-Up을 사용해 Fibonacci를 구하는 경우
public static int bottomUp(int n){
// 기저 상태의 경우 사전에 미리 저장
bottomup_table[0] = 0; bottomup_table[1] = 1;
// 반복문을 사용하고 있음!
for(int i=2; i<=n; i++){
// Table을 채워나감!
bottomup_table[i] = bottomup_table[i-1] + bottomup_table[i-2];
}
return bottomup_table[n];
}
}
/*
결과
832040
일반 재귀 소요 시간 : 9
832040
Top-Down DP 소요 시간 : 0
832040
Bottom-Up DP 소요 시간 : 0
*/
-
AWS EC2를 활용한 서버 배포
백엔드 개발의 마지막 단계는 개발을 완료한 서버를 배포하는 것이다!
이번 포스팅에서는 express.js로 개발한 서버를 AWS EC2 서비스를 활용하여 배포하는 방법을 단계별로 기록하겠습니다.
AWS EC2가 뭘까?
Amazon EC2(Elastic Compute Cloud)는 AWS(Amazon Web Services)의 클라우드 컴퓨팅 서비스로, 가상 서버인 인스턴스를 제공하여 사용자가 애플리케이션을 실행할 수 있도록 해줍니다.
사용자는 다양한 인스턴스 유형, CPU, 메모리, 스토리지 및 네트워킹 용량 등을 선택하여 필요한 리소스를 갖출 수 있습니다.
주요 특징
가상 서버 제공
EC2는 클라우드 환경에서 사용자가 가상 컴퓨터를 임대하여 애플리케이션을 실행할 수 있게 해줍니다.
다양한 인스턴스 유형
CPU, 메모리, 스토리지, 네트워킹 용량 등을 조합하여 다양한 인스턴스 유형을 제공하며, 애플리케이션의 요구사항에 맞는 인스턴스를 선택할 수 있습니다.
크기 조정 가능
EC2 인스턴스는 필요에 따라 용량을 늘리거나 줄일 수 있으며, 사용량에 따라 지불하는 방식인 온디맨드 인스턴스, 절감형 플랜, 스팟 인스턴스 등 다양한 요금 방식이 있습니다.
안전성
AWS의 강력한 보안 인프라를 활용하여 EC2 인스턴스를 안전하게 운영할 수 있습니다.
간편한 웹 인터페이스
AWS Management Console을 통해 EC2 인스턴스를 생성하고 관리할 수 있습니다.
네트워킹
EC2는 다양한 네트워킹 기능을 제공하며, 인스턴스 간 통신, 외부 접속 등을 설정할 수 있습니다.
다양한 운영체제 지원
EC2는 Windows, Linux, macOS 등 다양한 운영체제를 지원하며, 사용자 환경에 맞는 운영체제를 선택할 수 있습니다.
—
EC2 인스턴스를 사용하면 클라우드 환경에서 애플리케이션을 개발하고 배포할 수 있습니다.
하드웨어 제약 없이 컴퓨팅 용량을 확장할 수 있습니다.
다양한 인스턴스 유형을 활용하여 애플리케이션의 성능을 최적화할 수 있습니다.
사용량에 따라 비용을 지불할 수 있어 비용 효율성을 높일 수 있습니다.
EC2를 활용하여 서버 배포하는 방법은?
EC2로 서버를 배포하려면 당연히 AWS에 회원가입을 해야한다.
그런 다음 EC2 인스턴스를 생성하고 RDS (Relational Database Service)로 데이터베이스를 생성하여 서로 연결해줘야 한다.
이번 포스팅에서는 EC2 인스턴스를 생성하는 방법 위주로 다루고 다음 포스팅에서 RDS 데이터베이스에 대해 다룰 예정이다.
EC2 인스턴스 생성하기
1. 지역 → 아시아 태평양(서울)로 설정
2. EC2 → 인스턴스 시작
3. 서버 선택
4. 인스턴스 유형 선택
5. HTTP, HTTPS 허용
6. 키 페어 생성
7. 인스턴스 시작
EC2 인스턴스에서 프로젝트 실행하기
1. EC2 인스턴스 실행
2. EC2 에서 깃허브 활용 프로젝트 Clone
3. EC2 에서 의존성 패키치 설치
4. .env 파일 추가
5. DB 연결 후 생성
6. 프로젝트 실행
cf. background process : pm2
이번 프로젝트에서 사용한 express.js(node)는 foreground process이기 때문에 터미널이 종료되면 원격 서버도 함께 종료됩니다.
만약 실수로 원격으로 접속해 놓은 shell을 끄면(ubuntu@ 경로에서 exit; 명령어를 입력했거나 개발 환경 창을 종료한 경우) 로컬 경로(C:)로 돌아가고 원격에 접속해 있던 shell이 종료되기 때문에 원격 서버도 함께 종료됩니다.
하루종일 원격 서버에 접속해 두긴 어렵기 때문에 background process를 사용하면 shell의 종료 여부와 관계없이 원격 서버를 계속 실행할 수 있습니다.
background process를 사용하는 방법 중 하나는 pm2 라이브러리를 사용하는 것입니다.
포스팅이 너무 길어져서 pm2 적용도 다음 포스팅에서 다루도록 하겠습니다!
-continue
-
-
호출 스택과 실행 컨텍스트
JavaScript 주요 개념 시리즈 2, 4번째 키워드!
호출 스택 (실행 컨텍스트 스택)과 실행 컨텍스트에 대해 정리하겠습니다.
두 개념은 아주 긴밀한 관련이 있으니 함께 알아두시면 좋을 것 같습니다.
그럼 시작하겠습니다!
23. 실행 컨텍스트
23.1. 소스코드의 타입
ECMAScript 사양은 소스코드를 4가지 타입으로 구분함.
전역 코드, 함수 코드, eval 코드, 모듈 코드 4가지 타입의 소스코드는 실행 컨텍스트를 생성함.
타입에 따라 실행 컨텍스트를 생성하는 과정과 관리 내용이 다름.
23.2. 소스코드의 평가와 실행
실행에 앞서 평가 과정을 거침.
평가 과정에서 실행 컨텍스트를 생성하고 변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록함.
선언문을 제외한 소스코드가 순차적으로 실행됨.(런타임)
실행에 필요한 정보, 즉 변수나 함수의 참조를 실행 컨텍스트가 관리하는 스코프에서 검색하여 취득함.
변수 값의 변경 등 소스코드의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록됨.
23.3.실행 컨텍스트의 역할
전역 코드 평가
선언문만 먼저 실행 -> 생성된 전역 변수와 전역 함수가 전역 스코프에 등록됨. -> 전역 변수, 전역 함수는 전역 객체의 프로퍼티와 메서드가 됨.
전역 코드 실행
전역 코드가 순차적으로 실행됨. -> 전역 변수에 값이 할당되고 함수가 호출됨. -> 함수가 호출되면 순차적으로 실행되던 전역 코드의 실행을 일시 중단하고 코드 실행 순서를 변경하여 함수 내부로 진입함.
함수 코드 평가
매개 변수와 지역 변수 선언문이 먼저 실행되고 생성된 매개변수와 지역 변수가 지역 스코프에 등록됨.
argument 객체가 생성되어 지역 스코프에 등록되고 this 바인딩도 결정됨.
함수 코드 실행
매개변수와 지역 변수에 값이 할당됨.
함수 코드 실행 과정이 종료되고 함수 호출 이전으로 되돌아가 전역 코드 실행을 계속 함.
코그가 실행되려면 스코프를 구분하여 식별자와 바인딩된 값이 관리되어야 함.
중첩 관계에 의해 스코프 체인을 형성하여 식별자를 검색할 수 있어야 하고, 전역 객체의 프로퍼티도 전역 변수처럼 검색 할 수 있어야함.
함수 호출이 종료되면 함수 호출 이전으로 되돌아가기 위해 현재 실행 중인 코드와 이전에 실행하던 코드를 구분하여 관리해야 함.
이를 위해 모든 코드는 실행 컨텍스트를 통해 실행되고 관리됨.
식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고 코드 실행 순서는 실행 컨텍스트 스택으로 관리함.
23.4. 실행 컨텍스트 스택
생성된 실행 컨텍스트는 스택 자료구조로 관리됨. 이를 실행 컨텍스트 스택이라 함.
실행 컨텍스트 스택은 코드의 실행 순서를 관리함.
소스코드가 평가되면 실행 컨텍스트가 생성되고 실행 컨텍스트 스택의 최상위에 쌓임.
최상위에 존재하는 실행 컨텍스트는 언제나 현재 실행 중인 코드의 실행 컨텍스트이고 이를 실행 중인 실행 컨텍스트라고 함.
23.5. 렉시컬 환경
렉시컬 환경은 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트 임.
실행 컨텍스트는 LexicalEnvironment 컴포넌트와 VariableEnvironment 컴포넌트로 구성됨.
렉시컬 환경은 환경 레코드와 외부 렉시컬 환경에 대한 참조 두 개의 컴포넌트로 구성됨.
환경 레코드 : 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소
외부 렉시컬 환경에 대한 참조 : 상위 스코프를 가리킴. 스코프 체인을 구현함.
23.6. 실행 컨텍스트의 생성과 식별자 검색 과정
다음 코드를 참고하여 아래 설명을 이해하자!
var x = 1;
const y = 2;
function foo (a) {
var x = 3;
const y = 4;
function bar (b) {
const z = 5;
console.log(a+b+x+y+z);
}
bar(10);
}
foo(20);
23.6.1. 전역 객체 생성
전역 객체는 전역 코드가 평가되기 이전에 생성됨.
23.6.2. 전역 코드 평가
전역 실행 컨텍스트 생성
비어있는 전역 실행 컨텍스트를 생성하여 실행 컨텍스트 스택에 push 함.
전역 렉시컬 환경 생성
전역 렉시컬 환경을 생성하고 전역 실행 컨텍스트에 바인딩함.
렉시컬 환경은 환경 레코드와 외부 렉시컬 환경에 대한 참조로 구성됨.
전역 환경 레코드 생성
전역 환경 레코드는 전역 변수를 관리하는 전역 스코프, 전역 객체의 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 제공 함.
전역 환경 레코드는 객체 환경 레코드와 선언적 환경 레코드로 구성됨.
객체 환경 레코드는 var 전역 변수와 함수 선언문 정의 전역 함수, 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 관리하고 선언적 환경 레코드는 let, const 전역 변수를 관리함.
객체 환경 레코드 생성
객체 환경 레코드는 BindingObject라고 부르는 객체와 연결된 전역 객체 생성에서 생성된 전역 객체임.
전역 코드 평가 과정에서 var 전역 변수와 함수 선언문 정의 전역 함수는 객체 환경 레코드에 연결된 BindingObject를 통해 전역 객체의 프로퍼티와 메서드가 됨.
선언적 환경 레코드 생성
let, const 전역 변수는 선언적 환경 레코드에 등록되고 관리됨.
이들은 선언 단계와 초기화 단계가 분리되어 진행되어 변수 호이스팅이 발생하여도 런타임에 변수 선언문에 도달 전까지 일시적 사각지대에 빠지기 때문에 런타임에 변수 선언문에 도달 전까지 참조 불가함.
this 바인딩
전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 this(전역 객체)가 바인딩됨.
this 바인딩은 전역 환경 레코드와 함수 환경 레코드에만 존재함.
외부 렉시컬 환경에 대한 참조 결정
현재 평가 중인 소스코드를 포함하고 있는 외부 소스코드의 렉시컬 환경, 즉 상위 스코프를 가리킴.
전역 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에는 null이 할당됨.
23.6.3. 전역 코드 실행
식별자 결정을 위해 식별자를 검색할 때는 실행 중인 실행 컨텍스트에서 식별자를 검색하기 시작함.
만약 실행 중인 컨텍스트의 렉시컬 환경에서 식별자를 검색할 수 없으면 외부 렉시컬 환경에 대한 참조가 가리키는 렉시컬 환경, 즉 상위 스코프로 이동하여 식별자를 검색함.(스코프 체인의 동작 원리)
23.6.4. foo 함수 코드 평가
함수 실행 컨텍스트 생성
함수 실행 컨텍스트는 함수 렉시컬 환경이 완성된 다음 실행 컨텍스트 스택에 Push됨.
함수 렉시컬 환경 생성
foo 함수 렉시컬 환경을 생성하고 foo 함수 실행 컨텍스트에 바인딩함.
함수 환경 레코드 생성
함수 환경 레코드는 매개변수, argument 객체, 함수 내부에서 선언한 지역 변수와 중첩 함수를 등록하고 관리함.
this 바인딩
함수 환경 레코드의 [[ThisValue]] 내부 슬롯에 this가 바인딩됨.
일반 함수로 호출된 foo 함수의 [[ThisValue]]에는 전역 객체가 바인딩됨.
외부 렉시컬 환경에 대한 참조 결정
외부 렉시컬 환경에 대한 참조에 foo 함수 정의가 평가된 시점에 실행 중인 실행 컨텍스트의 렉시컬 환경의 참조가 할당됨.
즉, 전역 렉시컬 환경의 참조가 할당됨.
JS 엔진은 함수 정의를 평가하여 함수 객체를 생성할 때 현재 실행 중인 실행 컨텍스트의 렉시컬 환경, 즉 함수의 상위 스코프를 함수 객체의 내부 슬롯 [[Environment]]에 정장함.
함수 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 할당된 것은 함수 객체의 내부 슬롯 [[Environment]]에 저장된 렉시컬 환경의 참조임.
23.6.5. foo 함수 코드 실행
스코프 체인을 돌며 식별자 결정 진행.
23.6.6. bar 함수 코드 평가
23.6.7. bar 함수 코드 실행
console 식별자 검색
console 식별자를 스코프 체인에서 검색함.
스코프 체인은 현재 실행 중인 컨텍스트의 렉시컬 환경에서 시작하여 외부 렉시컬 환경에 대한 참조로 이어지는 렉시컬 환경의 연속임.
console 식별자는 객체 환경 레코드의 BindingObject를 통해 전역 객체에서 찾을 수 있음.
log 메서드 검색
console 객체에서 log 메서드를 검색함.
표현식 a+b+x+y+z의 평가
식별자는 스코프 체인에서 검색.
console.log 메서드 호출
표현식 a+b+x+y+z가 평가 되어 생성한 값 42를 console.log 메서드에 전달하여 호출함.
23.6.8. bar 함수 코드 실행 종료
bar 함수 코드의 실행이 종료됨. -> 실행 컨텍스트 스택에서 bar 함수 실행 컨텍스트가 pop되어 제거됨. -> foo 함수 실행 컨텍스트가 실행 중인 실행 컨텍스트가 됨.
bar 함수 실행 컨텍스트가 제거되었다고 해서 bar 함수 렉시컬 환경까지 즉시 소멸하는 것은 아님.
만약 bar 함수 렉시컬 환경을 누군가 참조하고 있다면 bar 함수 렉시컬 환경은 소멸하지 않음.
23.6.9. foo 함수 코드 실행 종료
foo 함수 코드의 실행이 종료됨. -> 실행 컨텍스트 스택에서 foo 함수 실행 컨텍스트가 pop되어 제거됨. -> 전역 실행 컨텍스트가 실행 중인 실행 컨텍스트가 됨.
23.6.10. 전역 코드 실행 종료
전역 코드의 실행이 종료되고 전역 실행 컨텍스트도 실행 컨텍스트 스택에서 제거되어 실행 컨텍스트 스택에는 아무것도 남지 않음.
23.7. 실행 컨텍스트와 블록 레벨 스코프
선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존의 전역 렉시컬 환경을 교체함.
이때 새롭게 생성된 코드 블록을 위한 렉시컬 환경의 외부 렉시컬 환경에 대한 참조는 코드 블록이 실행되기 전의 렉시컬 환경을 가리킴.
코드 블록의 실행이 종료되면 코드 블록이 실행되기 전의 렉시컬 환경으로 되돌아감.
for 문의 변수 선언문에 let 키워들 사용한 for 문은 코드 블록이 반복해서 실행될 때마다 코드 블록을 위한 렉시컬 환경을 생성함.
만약 for문 내에 함수가 있다면 이 함수의 상위 스코프는 for 문의 코드 블록이 생성한 렉시컬 환경이 됨.
이때 함수의 상위 스코프는 for 문의 코드 블록이 반복해서 실행될 때 마다 식별자(for문의 변수 등)의 값을 유지해야 함.
이를 위해 코드 블록이 반복 실행될 때마다 독립적인 렉시컬 환경을 생성하여 식별자의 값을 유지해야 함.(클로저)
이상 호출 스택과 실행 컨텍스트 정리였습니다.
-end-
-
-
-
-
-
-
-
-
Manage blog comments with Giscus
Giscus is a free comments system powered without your own database. Giscus uses the Github Discussions to store and load associated comments based on a chosen mapping (URL, pathname, title, etc.).
To comment, visitors must authorize the giscus app to post on their behalf using the GitHub OAuth flow. Alternatively, visitors can comment on the GitHub Discussion directly. You can moderate the comments on GitHub.
Prerequisites
Create a github repo
You need a GitHub repository first. If you gonna use GitHub Pages for hosting your website, you can choose the corresponding repository (i.e., [userID].github.io)
The repository should be public, otherwise visitors will not be able to view the discussion.
Turn on Discussion feature
In your GitHub repository Settings, make sure that General > Features > Discussions feature is enabled.
Activate Giscus API
Follow the steps in Configuration guide. Make sure the verification of your repository is successful.
Then, scroll down from the manual page and choose the Discussion Category options. You don’t need to touch other configs.
Copy _config.yml
Now, you get the giscus script. Copy the four properties marked with a red box as shown below:
Paste those values to _config.yml placed in the root directory.
# External API
giscus_repo: "[ENTER REPO HERE]"
giscus_repoId: "[ENTER REPO ID HERE]"
giscus_category: "[ENTER CATEGORY NAME HERE]"
giscus_categoryId: "[ENTER CATEGORY ID HERE]"
-
-
Markdown from A to Z
Headings
To create a heading, add number signs (#) in front of a word or phrase. The number of number signs you use should correspond to the heading level. For example, to create a heading level three (<h3>), use three number signs (e.g., ### My Header).
Markdown
HTML
Rendered Output
# Header 1
<h1>Header 1</h1>
Header 1
## Header 2
<h2>Header 2</h2>
Header 2
### Header 3
<h3>Header 3</h3>
Header 3
Emphasis
You can add emphasis by making text bold or italic.
Bold
To bold text, add two asterisks (e.g., **text** = text) or underscores before and after a word or phrase. To bold the middle of a word for emphasis, add two asterisks without spaces around the letters.
Italic
To italicize text, add one asterisk (e.g., *text* = text) or underscore before and after a word or phrase. To italicize the middle of a word for emphasis, add one asterisk without spaces around the letters.
Blockquotes
To create a blockquote, add a > in front of a paragraph.
> Yongha Kim is the best developer in the world.
>
> Factos 👍👀
Yongha Kim is the best developer in the world.
Factos 👍👀
Lists
You can organize items into ordered and unordered lists.
Ordered Lists
To create an ordered list, add line items with numbers followed by periods. The numbers don’t have to be in numerical order, but the list should start with the number one.
1. First item
2. Second item
3. Third item
4. Fourth item
First item
Second item
Third item
Fourth item
Unordered Lists
To create an unordered list, add dashes (-), asterisks (*), or plus signs (+) in front of line items. Indent one or more items to create a nested list.
* First item
* Second item
* Third item
* Fourth item
First item
Second item
Third item
Fourth item
Code
To denote a word or phrase as code, enclose it in backticks (`).
Markdown
HTML
Rendered Output
At the command prompt, type `nano`.
At the command prompt, type <code>nano</code>.
At the command prompt, type nano.
Escaping Backticks
If the word or phrase you want to denote as code includes one or more backticks, you can escape it by enclosing the word or phrase in double backticks (``).
Markdown
HTML
Rendered Output
``Use `code` in your Markdown file.``
<code>Use `code` in your Markdown file.</code>
Use `code` in your Markdown file.
Code Blocks
To create code blocks that spans multiple lines of code, set the text inside three or more backquotes ( ``` ) or tildes ( ~~~ ).
<html>
<head>
</head>
</html>
def foo():
a = 1
for i in [1,2,3]:
a += i
Horizontal Rules
To create a horizontal rule, use three or more asterisks (***), dashes (---), or underscores (___) on a line by themselves.
***
---
_________________
Links
To create a link, enclose the link text in brackets (e.g., [Blue Archive]) and then follow it immediately with the URL in parentheses (e.g., (https://bluearchive.nexon.com)).
My favorite mobile game is [Blue Archive](https://bluearchive.nexon.com).
The rendered output looks like this:
My favorite mobile game is Blue Archive.
Adding Titles
You can optionally add a title for a link. This will appear as a tooltip when the user hovers over the link. To add a title, enclose it in quotation marks after the URL.
My favorite mobile game is [Blue Archive](https://bluearchive.nexon.com "All senseis are welcome!").
The rendered output looks like this:
My favorite mobile game is Blue Archive.
URLs and Email Addresses
To quickly turn a URL or email address into a link, enclose it in angle brackets.
<https://www.youtube.com/>
<fake@example.com>
The rendered output looks like this:
https://www.youtube.com/
fake@example.com
Images
To add an image, add an exclamation mark (!), followed by alt text in brackets, and the path or URL to the image asset in parentheses. You can optionally add a title in quotation marks after the path or URL.

The rendered output looks like this:
Linking Images
To add a link to an image, enclose the Markdown for the image in brackets, and then add the link in parentheses.
[](https://www.britannica.com/place/La-Mancha)
The rendered output looks like this:
Escaping Characters
To display a literal character that would otherwise be used to format text in a Markdown document, add a backslash (\) in front of the character.
\* Without the backslash, this would be a bullet in an unordered list.
The rendered output looks like this:
* Without the backslash, this would be a bullet in an unordered list.
Characters You Can Escape
You can use a backslash to escape the following characters.
Character
Name
`
backtick
*
asterisk
_
underscore
{}
curly braces
[]
brackets
<>
angle brackets
()
parentheses
#
pound sign
+
plus sign
-
minus sign (hyphen)
.
dot
!
exclamation mark
|
pipe
HTML
Many Markdown applications allow you to use HTML tags in Markdown-formatted text. This is helpful if you prefer certain HTML tags to Markdown syntax. For example, some people find it easier to use HTML tags for images. Using HTML is also helpful when you need to change the attributes of an element, like specifying the color of text or changing the width of an image.
To use HTML, place the tags in the text of your Markdown-formatted file.
This **word** is bold. This <span style="font-style: italic;">word</span> is italic.
The rendered output looks like this:
This word is bold. This word is italic.
Touch background to close