Timeline
09:00 ~ 10:00 : 회의 (최종 웹 개발 검토)
10:00 ~ 13:00 : 개인 학습
13:00 ~ 14:00 : 점심 시간
14:00 ~ 18:00 : 개인 학습
18:00 ~ 19:00 : 저녁 시간
19:00 ~ 21:00 : 개인 학습 및 TIL 작성
Git 컨벤션(Git Commit Convention)이란?
Git에서 협업할 때, 일관된 커밋 메시지 스타일을 유지하기 위한 규칙
즉, 팀원들이 커밋을 남길 때 일정한 형식과 규칙을 지키도록 정한 가이드라인
✅ 프로젝트의 변경 사항을 체계적으로 관리하기 위해
✅ CI/CD 자동화 도구와 연동될 때(예: semantic-release), 커밋 메시지를 기반으로 버전 관리를 자동화하기 위해
1️⃣ 가장 널리 쓰이는 Git 컨벤션: Conventional Commits
Conventional Commits는 커밋 메시지를 특정 형식으로 작성하는 가장 유명한 컨벤션
📌 기본 구조
<타입>: <커밋 메시지 (간단한 설명)>
<필요 시, 본문>
<필요 시, 관련 이슈 번호>
예제
git commit -m "feat: 회원가입 기능 추가"
git commit -m "fix: 로그인 시 비밀번호 검증 오류 해결"
git commit -m "docs: README 업데이트"
git commit -m "refactor: 중복된 코드 제거 및 함수 분리"
2️⃣ Conventional Commits 상세 규칙
feat : 새로운 기능 추가
fix : 버그 수정
docs : 문서 수정 (README.md, API 문서 등)
style : 코드 스타일 변경 (세미콜론 추가, 공백 수정 등, 기능 변경 X)
refactor : 코드 리팩토링 (기능 변경 없이 코드 구조 개선)
perf : 성능 개선
test : 테스트 코드 추가/수정
chore : 빌드, 패키지 매니저 설정 변경 등
ci : CI/CD 설정 변경 (예: GitHub Actions 수정)
3️⃣ Conventional Commits + 본문 + 이슈 연동
fix: 로그인 시 비밀번호 검증 오류 해결
- 비밀번호 검증 로직이 잘못된 정규식을 사용하고 있었음
- 기존 `/\w+/` -> `/^[a-zA-Z0-9]{8,}$/` 로 변경
Closes #23
4️⃣ Git 커밋 메시지 예쁜 스타일
✔ 제목은 50자 이내로 짧게
✔ 첫 글자는 소문자로 시작 (영문)
✔ 제목 끝에 마침표(.) 넣지 않기
✔ 본문은 72자 단위로 줄 바꿈
5️⃣ Git 컨벤션을 자동으로 적용하는 방법
커밋 컨벤션을 강제하기 위해 Git Hook과 Husky를 사용할 수도 있음
• Husky → Git Hook을 활용하여 커밋 전에 컨벤션 체크
• Commitlint → 커밋 메시지가 컨벤션에 맞는지 검증
Husky + Commitlint 설정 예제
npm install --save-dev husky @commitlint/{cli,config-conventional}
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
npx husky install
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
async, await 복습
자바스크립트는 싱글 스레드(Single Thread) 언어라서, 하나의 코드가 실행 중이면 다른 코드가 실행되지 않음.
자바스크립트는 웹 개발에서 많이 사용되는데, 웹에서 데이터를 가져오거나 사용자 입력을 기다릴 때는 시간이 걸리는 작업이 많음.
💡 이런 작업을 비동기(Asynchronous) 방식으로 처리하지 않으면, 웹페이지가 멈추거나 느려지는 문제가 발생할 수 있음.
📌 비동기적으로 네트워크 작업 fetch를 사용하면?
function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve("데이터 로딩 완료!"), 3000); // 3초 후 데이터 반환
});
}
console.log("1. 데이터 요청");
let data = fetchData(); // 🚨 3초 걸리는 작업
console.log("2. 응답 받은 데이터:", data); // ❌ 아직 데이터 없음
console.log("3. 다음 작업 실행");
1. 데이터 요청
2. 응답 받은 데이터: [object Promise] ❌ (아직 데이터가 없음)
3. 다음 작업 실행
(3초 후, 데이터 도착하지만 화면에 출력되지 않음)
🚨 비동기 작업을 그냥 호출하면, 데이터가 도착하기 전에 코드가 다음 줄로 넘어가 버려서 제대로 된 값이 안 나옴
✅ 3. await을 사용하면 동기처럼 쉽게 작성 가능!
async function main() {
console.log("1. 데이터 요청");
let data = await fetchData(); // ⏳ 여기서 3초 기다림
console.log("2. 응답 받은 데이터:", data);
console.log("3. 다음 작업 실행");
}
main();
console.log("4. fetchData()를 기다리는 동안 다른 코드 실행 가능!");
1. 데이터 요청
4. fetchData()를 기다리는 동안 다른 코드 실행 가능! ⬅ (멈추지 않고 다른 작업 가능)
(3초 후)
2. 응답 받은 데이터: 데이터 로딩 완료!
3. 다음 작업 실행
✅ await 덕분에 비동기 코드를 동기 코드처럼 쉽게 작성 가능
✅ console.log("4. ...")는 fetchData()를 기다리지 않고 실행됨 (비동기 처리)
💡 핵심 개념: 자바스크립트의 이벤트 루프(Event Loop)
자바스크립트는 **“싱글 스레드지만 비동기적으로 작업을 수행할 수 있는 구조”**를 가지고 있음.
이게 가능한 이유는 이벤트 루프(Event Loop)와 비동기 처리 방식 때문.
✅ 1. 자바스크립트의 실행 구조
자바스크립트는 기본적으로 **싱글 스레드(Single Thread)**로 한 번에 한 줄씩 코드를 실행하는데,
백그라운드에서 비동기 작업을 처리할 수 있도록 이벤트 루프(Event Loop)를 활용할 수 있음.
📌 싱글 스레드의 기본적인 실행 방식
async function fetchData() {
console.log("1. 데이터 요청");
let result = await new Promise(resolve => {
setTimeout(() => resolve("📄 데이터 로딩 완료!"), 3000);
});
console.log("2. 응답 받은 데이터:", result);
}
fetchData();
console.log("3. 다음 작업 실행");
1. 데이터 요청
3. 다음 작업 실행 ⬅ (비동기 작업을 기다리지 않고 실행됨)
(3초 후)
2. 응답 받은 데이터: 📄 데이터 로딩 완료!
💡 이게 어떻게 가능한 걸까?
• setTimeout() 함수는 Web API(백그라운드)에서 실행됨.
• 메인 스레드는 다음 코드(console.log("3. 끝"))로 바로 이동.
• setTimeout()이 끝나면 **이벤트 루프(Event Loop)**가 실행되면서 백그라운드 작업을 다시 메인 스레드로 가져와 실행.
✅ 2. 비동기 작업을 다루는 이벤트 루프(Event Loop)의 역할
자바스크립트는 setTimeout(), fetch(), Promise, async/await 같은 비동기 작업을 사용할 때 **이벤트 루프(Event Loop)**를 이용해 코드 실행을 관리.
📌 이벤트 루프의 동작 방식
1. Call Stack(콜 스택)
• 현재 실행 중인 함수가 쌓이는 공간 (싱글 스레드에서 실행)
2. Web APIs(백그라운드)
• setTimeout(), fetch(), Promise 같은 비동기 작업을 실행할 수 있는 영역.
3. Callback Queue(콜백 큐)
• 백그라운드에서 완료된 작업들이 대기하는 곳.
4. Event Loop(이벤트 루프)
• 콜백 큐에 있는 작업을 콜 스택이 비었을 때 다시 실행하는 역할.
✅ 싱글 스레드인데 동시에 다른 코드가 실행되는 이유
이벤트 루프와 백그라운드(Web APIs) 기능으로 인해 가능
1. fetchData() 실행
• "1. 데이터 요청" 출력.
• await를 만나서 비동기 작업이 백그라운드(Web APIs)로 이동.
2. 메인 스레드는 await를 기다리지 않고 다음 코드 실행
• "3. 다음 작업 실행" 출력.
3. 3초 후 비동기 작업이 완료되면, 이벤트 루프가 다시 실행
• "2. 응답 받은 데이터: 📄 데이터 로딩 완료!" 출력.
💡 즉, **“한 개의 스레드에서 작업을 하나씩 실행하지만, 기다리는 동안 다른 코드가 실행될 수 있도록 관리하는 방식”**.
그럼, 또 궁금한 부분이 생김.
콜백 큐(Callback Queue)에 대기 중인 작업과 새로운 함수 실행 중인 코드가 있을 때,
**이벤트 루프(Event Loop)**는 어떤 걸 먼저 실행하는지? 🤔
✅ 1. 자바스크립트의 실행 우선순위
자바스크립트의 실행 순서는 두 가지 큐에 따라 달라짐:
1. 마이크로태스크 큐(Microtask Queue)
• Promise.then(), MutationObserver, queueMicrotask() 같은 비동기 작업이 여기에 들어감.
• 💡 이벤트 루프는 항상 마이크로태스크 큐를 먼저 처리!
2. 태스크 큐(Task Queue) (or 콜백 큐)
• setTimeout(), setInterval(), setImmediate(), I/O 작업 같은 비동기 작업이 여기에 들어감.
• 마이크로태스크가 비어야 실행됨.
📌 실행 순서 요약
1️⃣ 콜 스택(Call Stack)이 비었는지 확인
2️⃣ 마이크로태스크 큐(Microtask Queue) 실행 (Promise 등)
3️⃣ 태스크 큐(Task Queue) 실행 (setTimeout 등)
즉, 마이크로태스크가 있으면 먼저 실행되고, 그 다음에 태스크 큐에서 실행됨.
console.log("1. 시작");
setTimeout(() => {
console.log("2. setTimeout 실행");
}, 0);
Promise.resolve().then(() => {
console.log("3. Promise 실행");
});
console.log("4. 끝");
1. 시작
4. 끝 ⬅ (동기 코드 실행)
3. Promise 실행 ⬅ (마이크로태스크 큐 먼저 실행)
2. setTimeout 실행 ⬅ (태스크 큐 실행)
✅ 예제 2: setTimeout() vs 일반 함수 실행 순서
console.log("1. 시작");
setTimeout(() => {
console.log("2. setTimeout 실행");
}, 0);
function nextTask() {
console.log("3. 다음 함수 실행");
}
nextTask();
console.log("4. 끝");
1. 시작
3. 다음 함수 실행 ⬅ (동기 코드 실행)
4. 끝 ⬅ (동기 코드 실행)
2. setTimeout 실행 ⬅ (이제야 실행됨)
✅ 예제 3: 마이크로태스크 vs setTimeout vs 다음 실행할 함수
console.log("1. 시작");
setTimeout(() => {
console.log("2. setTimeout 실행");
}, 0);
Promise.resolve().then(() => {
console.log("3. Promise 실행");
});
function nextTask() {
console.log("4. 다음 함수 실행");
}
nextTask();
console.log("5. 끝");
1. 시작
4. 다음 함수 실행 ⬅ (동기 코드 실행)
5. 끝 ⬅ (동기 코드 실행)
3. Promise 실행 ⬅ (마이크로태스크 큐 실행)
2. setTimeout 실행 ⬅ (이제야 실행됨)
추가 : 싱글 스레드 언어 VS 멀티 스레드 언어
✅ 1. 싱글 스레드 vs 멀티 스레드 개념
✔ 싱글 스레드(Single-threaded)
• 한 번에 하나의 작업만 실행 가능.
• 예: 자바스크립트(JavaScript), Python(기본 실행 방식)
✔ 멀티 스레드(Multi-threaded)
• 여러 개의 작업을 동시에 실행 가능.
• 예: Java, C++, C#, Python(멀티스레드 지원), Go
✅ 2. 언어별 스레드 지원 방식
언어 | 기본 실행 방식 | 멀티스레드 지원 여부 | 비고 |
JavaScript | 싱글 스레드 | ❌(기본 실행) ✅(Web Worker) | 이벤트 루프 + 비동기 처리 (async/await, Promise) |
Python | 싱글 스레드 | ✅(멀티스레드 지원) | GIL(Global Interpreter Lock) 때문에 한계 있음 |
Java | 멀티 스레드 | ✅ | Thread 클래스, Runnable 인터페이스 |
C++ | 멀티 스레드 | ✅ | std::thread 사용 |
C# | 멀티 스레드 | ✅ | Task, Thread 클래스 |
Go | 멀티 스레드 | ✅ | goroutine 사용 (가볍고 효율적인 스레드) |
Rust | 멀티 스레드 | ✅ | 안전한 멀티스레드 지원 |
Python은 GIL(Global Interpreter Lock) 때문에 멀티스레드 성능이 떨어짐.
그래서 멀티 프로세스(multiprocessing) 방식을 사용해서 진짜 병렬 실행 가능!
from multiprocessing import Process
def task():
print("멀티 프로세스 실행!")
p = Process(target=task)
p.start() # 별도 프로세스에서 실행됨
p.join()
Java는 기본적으로 멀티 스레드 지원! 🚀
class MyThread extends Thread {
public void run() {
System.out.println("멀티 스레드 실행 중!");
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // 새로운 스레드에서 실행됨
}
}
✅ 3. 결론: 싱글 스레드 vs 멀티 스레드 요약
특징 | 싱글 스레드 (JavaScript, Python 기본 실행) | 멀티 스레드 (Java, C++, C# 등) |
실행 방식 | 한 번에 하나의 작업 실행 | 여러 작업을 동시에 실행 가능 |
동시 작업 | 이벤트 루프 + 비동기 처리 | 여러 스레드에서 병렬 실행 |
속도 | IO 작업에 유리 (네트워크, DB) | CPU 작업에 유리 (연산, 병렬 처리) |
사용 예시 | 웹 브라우저, Node.js 서버 | 게임, AI, 영상 처리 |
코드 스타일 : 식별자(변수, 함수명, 타입명, 이름공간(네임스페이스) 작성 규칙
언어에 따라 적절히 표기법을 혼합한다.
예를 들어 Java의 경우 변수, 메서드 등에서는 카멜 표기법, 클래스 등의 타입에는 파스칼 표기법, 상수에는 대문자 스네이크 표기법이 권장되고 있다. C#은 Java와 비슷하지만 메서드에도 파스칼 표기법으로 쓴다는 점이 다르다. 파일명의 경우 보통은 스네이크 표기법이 권장되고 있으나, Java, C# 등 일부 언어에서는 (대표) 타입명과 동일한 파일 이름을 권장하기도 한다.
https://namu.wiki/w/%EC%BD%94%EB%94%A9%20%EC%8A%A4%ED%83%80%EC%9D%BC#s-3
코딩 스타일
Code Conventions 소스 코드 의 가독성을 올리고 혼동을 피하기 위해 작성 시 지키도록 강제되는 불문율
namu.wiki
카멜 표기법(Camel Case)
camelCase
낙타의 등에 있는 혹과 같다고 하여 카멜(Camel) 표기법이라고 부른다.
봉이 하나이기 때문에 단봉낙타 표기법이라고도 하며, 파스칼 표기법과 비교하여 lowerCamelCase라고도 한다.
중간에 식별자 이름에 약자가 포함되어 있는 경우 해당 약자를 모두 대문자로 쓸 수도 있다. (parsedXMLElement)
파스칼 표기법(Pascal Case)
PascalCase
맨 앞에 오는 문자까지도 대문자로 표기한다.
카멜 표기법과 비교하여 UpperCamelCase라고도 하며, 봉이 둘이기 때문에 쌍봉낙타 표기법이라고도 한다.
타입 정의에는 파스칼 표기가 대세이다.
스네이크 표기법(Snake Case)
snake_case
단어 사이에 언더바_를 넣어서 표기하는 것이다.
Screaming Snake Case
SCREAMING_SNAKE_CASE
단어 구분자로 _를 사용하지만, 나머지 문자를 전부 대문자로 적는 표기법. MACRO_CASE라고도 부른다.
주로 상수 정의, 환경 번수 정의 등에 사용된다. 한글 등에는 없는 특징이지만 영어에서 문장을 전부 대문자로 적을 경우 굉장히 강조되어, 마치 화자가 소리치는 것 같은 느낌을 준다. 따라서 주로 경고의 의미가 있거나, 사용 시 주의해야 하는 경우 이렇게 표기하기도 한다.
케밥 표기법(Kebab Case)
kebab-case
구분자로 -를 사용한다. 단어들이 마치 케밥 꼬치에 꽂힌 것처럼 보인다고 해서 붙은 이름이다.
헝가리안 표기법(Hungarian Notation)
strName, bBusy, szName
접두어에 자료형을 붙이다. 장점은 변수명만 봐도 자료형을 유추할 수 있어 가독성과 편의성이 향상된다는 것이다.
때문에 자료형 지원이 다양하지 않았던 시기에 자주 사용되었다. 단점은 접두어만큼 변수명이 길어지기 때문에 사람에 따라서는 오히려 역으로 가독성이 깎일 수 있다는 것과, 개발 도중에 자료형이 바뀐다면 모든 변수명을 수정해주어야 하는 난감한 상황이 연출된다는 것이다.
'코딩 > sparta TIL' 카테고리의 다른 글
TIL 7 : Java 문법 종합반 2주차 (0) | 2025.02.24 |
---|---|
TIL 6 : Java 문법 종합반 1주차 (1) | 2025.02.24 |
TIL 5 : KPT (0) | 2025.02.21 |
TIL 2 : 깃허브&파이어베이스와 가까워지기 (0) | 2025.02.18 |
TIL 1 : 와이어프레임 & 팀명 구상하기, 기초 팀 페이지 만들기 (0) | 2025.02.17 |