Compare commits

...

4 Commits

Author SHA1 Message Date
dihwang a851025e43 노트추가 및 서버 이전 2026-05-12 14:59:58 +09:00
dihwang 722d5dbfaf 오랜만에 커밋 2026-05-04 10:30:04 +09:00
dihwang c35c042afa 스크립트 잘못되있어서 /home/dihwang 경로 다 날라감
방어스크립트로 변경
2026-04-10 11:48:51 +09:00
dihwang d3de1706be /home/dihwang -> /var/www 로 경로 변경 2026-04-10 11:21:08 +09:00
70 changed files with 2771 additions and 17 deletions
+14 -6
View File
@@ -43,9 +43,17 @@ jobs:
username: ${{ secrets.GCE_USERNAME }}
key: ${{ secrets.GCE_SSH_KEY }}
script: |
cd /home/dihwang/white-smith-blog/public
# 3. 서버에 남아있는 유령 파일들 싹 제거 (매우 중요)
find . -mindepth 1 -delete
# 4. 압축 해제
tar -xzf ../deploy.tar.gz
rm ../deploy.tar.gz
# 1. 대상 폴더가 없으면 미리 생성 (cd 실패 방지)
mkdir -p /var/www/white-smith-blog/public
# 2. 폴더 이동에 성공했을 때만(&&) 내부 파일 삭제 및 압축 해제 진행
cd /var/www/white-smith-blog/public && {
# 현재 폴더(public) 내의 모든 파일/폴더 삭제 (점 파일 포함)
find . -mindepth 1 -delete
# 상위 폴더에 전송된 압축 파일 해제
tar -xzf ../deploy.tar.gz
# 작업 완료 후 압축 파일 삭제
rm ../deploy.tar.gz
}
-1
View File
@@ -1 +0,0 @@
[[Aider 사용기]]
+2
View File
@@ -0,0 +1,2 @@
[[마력과 토크, RPM]]
@@ -0,0 +1,9 @@
[[Gitea & Quartz 배포 자동화 트러블슈팅]]
[[gitea, qurtz 설치]]
[[kui-vault]]
[[WebHook]]
@@ -1,5 +0,0 @@
## Language
[[파이썬(python) 통찰]]
## Tech
[[Functional Domain Modeling]]
+2
View File
@@ -0,0 +1,2 @@
[[전표처리]]
+4
View File
@@ -0,0 +1,4 @@
### Coding Agent
[[Aider 사용기]]
[[Aider 프로젝트 생성]]
+2
View File
@@ -0,0 +1,2 @@
[[Functional Domain Modeling]]
+2
View File
@@ -0,0 +1,2 @@
[[파이썬(python) 통찰]]
+5
View File
@@ -0,0 +1,5 @@
[[VPN으로 외부 DB에 접근]]
[[Pc끼리 Lan선으로 Direct 연결]]
[[RS-232와 이더넷 통신]]
+2
View File
@@ -0,0 +1,2 @@
### Server
[[어플리케이션(서비스) 실행 시 계정 구분하는 이유]]
+22
View File
@@ -0,0 +1,22 @@
---
id: "Aider 단축키 20260413"
created: "2026-04-13 13:35"
tags:
---
| **명령어** | **설명** | **비고** |
| --------------- | --------------------------------- | ----------------------------------- |
| **/undo** | **AI가 방금 수정한 코드를 취소하고 직전 상태로 복구** | 가장 자주 쓰임 |
| **/add <파일>** | 수정하거나 참고할 파일을 채팅창에 추가 | 파일명 일부만 쳐도 자동완성 |
| **/drop <파일>** | 채팅창에서 특정 파일 제외 | 실제 파일이 삭제되지는 않음 |
| **/ls** | 현재 채팅창에 포함된 파일 목록 확인 | |
| **/diff** | 마지막 수정 사항의 변경 전/후 차이점 표시 | |
| **/test <명령어>** | 테스트 명령을 실행하고 실패 시 AI가 자동 수정 | 예: `/test pytest` |
| **/model <모델>** | 사용 중인 AI 모델을 즉시 변경 | 예: `/model gemini/gemini-2.5-flash` |
| **/tokens** | 현재 세션의 토큰 사용량과 비용 정보 확인 | |
| **/run <명령어>** | 에이더를 나가지 않고 터미널 명령어 실행 | 예: `/run ls -al` |
| **/exit** | 에이더 종료 | `/quit`과 동일 |
| **/help** | 모든 명령어 목록과 상세 도움말 확인 | |
| **명령어** | **용도** | **특징** |
| **/ask <질문>** | 코드에 대해 질문하기 | 코드를 **직접 수정하지 않고** 설명만 해줍니다. |
| **/chat <메시지>** | 일반적인 대화/토론 | 파일 수정 없이 구현 방법이나 구조에 대해 논의할 때 씁니다. |
| **/code <명령>** | 코드 수정 요청 | 기본 모드입니다. 지시한 대로 파일을 직접 수정합니다. |
+689
View File
@@ -0,0 +1,689 @@
---
id: "Aider 최초 사용 20260413"
created: "2026-04-13 14:01"
tags:
---
Gemini를 채찍질해서 아래의 명세를 가지는 VaultKeeper 어플리케이션 구상을 함.
( kui-veil 서버의 auth 관리 어플리케이션임 )
```markdown
## 🏗️ VaultKeeper 프로젝트 상세 설계도 (Ver 2.0)
### 1. 개요
- **목적**: Nginx의 `.htpasswd` 파일을 웹 GUI를 통해 관리하는 초경량 도구.
- **타겟 환경**: Google Cloud e2-micro (저사양 서버).
- **주요 언어**: **Go** (백엔드), **Vanilla JS** (프론트엔드).
### 2. 보안 전략 (핵심)
- **인증 분리**: 백엔드 자체에 로그인 로직을 구현하지 않고, Nginx의 `auth_basic` 모듈에 인증을 위임함.
- **접근 권한**: 서버 관리자가 터미널에서 직접 생성한 계정으로만 웹 UI에 접근 가능.
- **입력값 검증**: `os/exec` 실행 시 쉘 인젝션을 방지하기 위해 사용자 이름에 특수문자 입력을 제한함.
### 3. 구성 요소
- **Backend (`main.go`)**:
- 환경 변수 `HTPASSWD_PATH`를 통해 대상 파일 경로 지정.
- 표준 패키지 `net/http`를 사용하여 메모리 점유 최소화.
- `htpasswd` 시스템 명령어를 서브프로세스로 호출하여 계정 추가/삭제.
- **Frontend (`index.html`)**:
- 단일 파일 SPA 구조.
- Tailwind CSS(CDN)를 활용한 직관적인 대시보드.
```
```markdown
## 🤖 에이더(Aider)를 위한 최종 지시서
아래 내용을 에이더 채팅창에 입력하시면 됩니다.
**프로젝트: VaultKeeper (Nginx .htpasswd 관리 도구)**
**1. 백엔드 구현 (`main.go`)**
- **언어**: Go (표준 라이브러리 위주로 매우 가볍게).
- **기능**:
- `GET /api/users`: `.htpasswd` 파일을 읽어 유저 목록을 JSON으로 반환.
- `POST /api/users`: `username`, `password`를 받아 `htpasswd -b` 실행.
- `DELETE /api/users/{username}`: `htpasswd -D` 실행.
- **보안**: 사용자 이름 입력값에서 쉘 인젝션이 발생하지 않도록 유효성 검사 로직 포함.
- **설정**: `.htpasswd` 경로를 환경 변수 `HTPASSWD_PATH`에서 읽어오도록 설정.
**2. 프론트엔드 구현 (`index.html`)**
- 단일 파일 SPA로 작성하고 Tailwind CSS를 사용하여 깔끔한 UI 제공.
- 유저 목록 표시, 추가 폼, 삭제 버튼 구현.
**3. 배포 가이드 (`deployment.md`) 생성**
- `go build`를 이용한 경량 바이너리 빌드 방법 (`-s -w` 옵션 포함).
- 터미널에서 최초 관리자 계정을 생성하는 명령어 안내.
- 이 서비스를 Nginx `auth_basic` 뒤에 배치하기 위한 `location` 블록 설정 예시. (8000번 포트 기준)
**주의**: 모든 코드와 문서에서 특정 개인의 이름이나 개인정보를 절대 포함하지 말고 `Admin` 또는 `User`와 같은 공용 용어만 사용해줘.
```
이걸 aider에게 먹이고 (add)
```bash
────────────────────────────────────────────────────────────────────────────────
> /add "doc/vault-keeper 상세 설계도.txt" "doc/지시서.txt"
Added doc\vault-keeper 상세 설계도.txt to the chat
Added doc\지시서.txt to the chat
────────────────────────────────────────────────────────────────────────────────
```
진행해보라고 했다.
```bash
doc\vault-keeper 상세 설계도.txt doc\지시서.txt
> 내가 추가한 상세 설계도와 지시서를 바탕으로 어플리케이션을 만들어봐
```
과연.. 결과는?
어.. 뭔가 만들어지긴 했다..
아래는 콘솔에 찍힌 내용 전체
요청하신 내용에 따라 애플리케이션을 만들겠습니다. main.go, index.html, deployment.md 파일을 새로 생성합니다.
다음은 필요한 SEARCH/REPLACE 블록입니다:
main.go
<<<<<<< SEARCH
=======
package main
import (
"bufio"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
"sync"
)
// User는 .htpasswd 파일의 사용자 정보를 나타냅니다.
type User struct {
Username string `json:"username"`
}
// AddUserRequest는 새 사용자 추가 요청에 사용됩니다.
type AddUserRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
var (
htpasswdPath string
htpasswdMutex sync.Mutex // htpasswd 명령 실행 시 동시성 문제를 방지하기 위한 뮤텍스
usernameRegex *regexp.Regexp // 사용자 이름 유효성 검사를 위한 정규식
)
func init() {
// HTPASSWD_PATH 환경 변수 설정
htpasswdPath = os.Getenv("HTPASSWD_PATH")
if htpasswdPath == "" {
log.Fatal("환경 변수 HTPASSWD_PATH가 설정되지 않았습니다.")
}
// 사용자 이름 유효성 검사 정규식 초기화: 영문, 숫자, 하이픈, 언더스코어만 허용
usernameRegex = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
}
func main() {
mux := http.NewServeMux()
// 정적 파일(index.html) 제공
mux.HandleFunc("/", serveFrontend)
// API 엔드포인트
mux.HandleFunc("/api/users", handleUsers)
mux.HandleFunc("/api/users/", handleDeleteUser) // DELETE 요청 처리
log.Println("VaultKeeper 서버가 8000 포트에서 시작됩니다.")
log.Printf("HTPASSWD_PATH: %s\n", htpasswdPath)
log.Fatal(http.ListenAndServe(":8000", mux))
}
// serveFrontend는 index.html 파일을 제공합니다.
func serveFrontend(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" || r.URL.Path == "/index.html" {
http.ServeFile(w, r, "index.html")
return
}
http.NotFound(w, r)
}
// handleUsers는 GET /api/users 및 POST /api/users 요청을 처리합니다.
func handleUsers(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
getUsers(w, r)
case http.MethodPost:
addUser(w, r)
default:
http.Error(w, "허용되지 않는 메소드입니다.", http.StatusMethodNotAllowed)
}
}
// getUsers는 .htpasswd 파일에서 사용자 목록을 읽어 JSON으로 반환합니다.
func getUsers(w http.ResponseWriter, r *http.Request) {
htpasswdMutex.Lock()
defer htpasswdMutex.Unlock()
file, err := os.Open(htpasswdPath)
if os.IsNotExist(err) {
// 파일이 없으면 빈 목록 반환 (처음 생성 시)
json.NewEncoder(w).Encode([]User{})
return
}
if err != nil {
log.Printf("Error opening .htpasswd file: %v", err)
http.Error(w, "사용자 파일을 읽을 수 없습니다.", http.StatusInternalServerError)
return
}
defer file.Close()
var users []User
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if len(line) > 0 && !strings.HasPrefix(line, "#") { // 주석 및 빈 줄 무시
parts := strings.SplitN(line, ":", 2)
if len(parts) > 0 {
users = append(users, User{Username: parts[0]})
}
}
}
if err := scanner.Err(); err != nil {
log.Printf("Error scanning .htpasswd file: %v", err)
http.Error(w, "사용자 파일을 스캔할 수 없습니다.", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
// addUser는 새 사용자를 .htpasswd 파일에 추가합니다.
func addUser(w http.ResponseWriter, r *http.Request) {
var req AddUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "유효하지 않은 요청 본문입니다.", http.StatusBadRequest)
return
}
// 사용자 이름 유효성 검사
if !usernameRegex.MatchString(req.Username) {
http.Error(w, "사용자 이름은 영문, 숫자, 하이픈, 언더스코어만 포함할 수 있습니다.", http.StatusBadRequest)
return
}
if req.Username == "" || req.Password == "" {
http.Error(w, "사용자 이름과 비밀번호는 필수입니다.", http.StatusBadRequest)
return
}
htpasswdMutex.Lock()
defer htpasswdMutex.Unlock()
// htpasswd -b <file> <username> <password>
// 파일이 없으면 -c 옵션이 필요하지만, 첫 생성은 터미널에서 하도록 가이드하므로 여기서는 -b만 사용.
// -b는 파일이 없으면 생성하고, 있으면 추가/수정합니다.
cmd := exec.Command("htpasswd", "-b", htpasswdPath, req.Username, req.Password)
output, err := cmd.CombinedOutput()
if err != nil {
log.Printf("Error executing htpasswd -b: %v, Output: %s", err, output)
http.Error(w, fmt.Sprintf("사용자 추가 실패: %s", strings.TrimSpace(string(output))), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"message": "사용자가 성공적으로 추가되었습니다."})
}
// handleDeleteUser는 DELETE /api/users/{username} 요청을 처리합니다.
func handleDeleteUser(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodDelete {
http.Error(w, "허용되지 않는 메소드입니다.", http.StatusMethodNotAllowed)
return
}
username := strings.TrimPrefix(r.URL.Path, "/api/users/")
if username == "" {
http.Error(w, "사용자 이름을 지정해야 합니다.", http.StatusBadRequest)
return
}
// 사용자 이름 유효성 검사 (삭제도 동일하게 적용)
if !usernameRegex.MatchString(username) {
http.Error(w, "유효하지 않은 사용자 이름 형식입니다.", http.StatusBadRequest)
return
}
htpasswdMutex.Lock()
defer htpasswdMutex.Unlock()
// htpasswd -D <file> <username>
cmd := exec.Command("htpasswd", "-D", htpasswdPath, username)
output, err := cmd.CombinedOutput()
if err != nil {
// htpasswd -D는 사용자가 존재하지 않을 경우에도 에러를 반환합니다.
// 그러나 사용자 삭제 요청 자체는 성공했다고 간주할 수 있습니다 (해당 사용자가 없는 상태이므로).
// 실제 htpasswd의 에러 메시지를 확인하여 사용자 부재인지 다른 에러인지 구분할 수 있으나,
// 간단하게 사용자 부재 메시지가 아니라면 서버 에러로 처리합니다.
if strings.Contains(strings.ToLower(string(output)), "not found") {
http.Error(w, fmt.Sprintf("사용자 '%s'를 찾을 수 없습니다.", username), http.StatusNotFound)
return
}
log.Printf("Error executing htpasswd -D: %v, Output: %s", err, output)
http.Error(w, fmt.Sprintf("사용자 삭제 실패: %s", strings.TrimSpace(string(output))), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(map[string]string{"message": fmt.Sprintf("사용자 '%s'가 성공적으로 삭제되었습니다.", username)})
}
>>>>>>> REPLACE
index.html
<<<<<<< SEARCH
=======
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VaultKeeper - Nginx .htpasswd 관리</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<style>
body {
background-color: #f3f4f6;
}
</style>
</head>
<body class="font-sans antialiased text-gray-900">
<div class="min-h-screen flex flex-col items-center justify-center p-4">
<div class="w-full max-w-2xl bg-white rounded-lg shadow-xl p-8 space-y-8">
<h1 class="text-3xl font-bold text-center text-gray-800">VaultKeeper</h1>
<p class="text-center text-gray-600">Nginx .htpasswd 파일 관리</p>
<!-- 사용자 추가 폼 -->
<div class="border-t border-gray-200 pt-8">
<h2 class="text-2xl font-semibold text-gray-800 mb-4">새 사용자 추가</h2>
<form id="addUserForm" class="space-y-4">
<div>
<label for="username" class="block text-sm font-medium text-gray-700">사용자 이름</label>
<input type="text" id="username" name="username" required
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none
focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">비밀번호</label>
<input type="password" id="password" name="password" required
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none
focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<button type="submit"
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm
font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
사용자 추가
</button>
</form>
<div id="addMessage" class="mt-3 text-center font-medium"></div>
</div>
<!-- 사용자 목록 -->
<div class="border-t border-gray-200 pt-8">
<h2 class="text-2xl font-semibold text-gray-800 mb-4">현재 사용자 목록</h2>
<div id="userListContainer">
<ul id="userList" class="divide-y divide-gray-200 bg-white rounded-md shadow-sm">
<!-- 사용자는 여기에 동적으로 로드됩니다. -->
</ul>
<p id="noUsersMessage" class="text-center text-gray-500 mt-4 hidden">등록된 사용자가 없습니다.</p>
</div>
<div id="listMessage" class="mt-3 text-center font-medium"></div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const addUserForm = document.getElementById('addUserForm');
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
const addMessageDiv = document.getElementById('addMessage');
const userList = document.getElementById('userList');
const noUsersMessage = document.getElementById('noUsersMessage');
const listMessageDiv = document.getElementById('listMessage');
async function fetchUsers() {
listMessageDiv.textContent = '';
userList.innerHTML = '';
try {
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const users = await response.json();
if (users.length === 0) {
noUsersMessage.classList.remove('hidden');
} else {
noUsersMessage.classList.add('hidden');
users.forEach(user => {
const li = document.createElement('li');
li.className = 'flex items-center justify-between p-4 hover:bg-gray-50';
li.innerHTML = `
<span class="text-lg font-medium">${user.username}</span>
<button data-username="${user.username}"
class="delete-btn bg-red-500 hover:bg-red-600 text-white font-bold py-1 px-3 rounded text-sm">
삭제
</button>
`;
userList.appendChild(li);
});
addDeleteEventListeners();
}
} catch (error) {
console.error('Error fetching users:', error);
listMessageDiv.textContent = `사용자 목록을 불러오는 데 실패했습니다: ${error.message}`;
listMessageDiv.className = 'mt-3 text-center font-medium text-red-600';
}
}
async function addUser(event) {
event.preventDefault();
addMessageDiv.textContent = '';
const username = usernameInput.value;
const password = passwordInput.value;
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password }),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || '사용자 추가 실패');
}
addMessageDiv.textContent = data.message;
addMessageDiv.className = 'mt-3 text-center font-medium text-green-600';
usernameInput.value = '';
passwordInput.value = '';
fetchUsers(); // 사용자 목록 새로 고침
} catch (error) {
console.error('Error adding user:', error);
addMessageDiv.textContent = `사용자 추가 실패: ${error.message}`;
addMessageDiv.className = 'mt-3 text-center font-medium text-red-600';
}
}
async function deleteUser(username) {
listMessageDiv.textContent = '';
if (!confirm(`사용자 '${username}'을(를) 정말 삭제하시겠습니까?`)) {
return;
}
try {
const response = await fetch(`/api/users/${username}`, {
method: 'DELETE',
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || '사용자 삭제 실패');
}
listMessageDiv.textContent = data.message;
listMessageDiv.className = 'mt-3 text-center font-medium text-green-600';
fetchUsers(); // 사용자 목록 새로 고침
} catch (error) {
console.error('Error deleting user:', error);
listMessageDiv.textContent = `사용자 삭제 실패: ${error.message}`;
listMessageDiv.className = 'mt-3 text-center font-medium text-red-600';
}
}
function addDeleteEventListeners() {
document.querySelectorAll('.delete-btn').forEach(button => {
button.onclick = () => deleteUser(button.dataset.username);
});
}
addUserForm.addEventListener('submit', addUser);
// 페이지 로드 시 사용자 목록 가져오기
fetchUsers();
});
</script>
</body>
</html>
>>>>>>> REPLACE
deployment.md
<<<<<<< SEARCH
=======
# VaultKeeper 배포 가이드
이 문서는 VaultKeeper 애플리케이션의 빌드, 초기 설정 및 Nginx 연동 방법을 안내합니다.
## 1. 백엔드 빌드
Go 바이너리를 가볍게 빌드하려면 다음 명령어를 사용합니다. 이 명령어는 디버그 정보를 제거하고 심볼 테이블을 생략하여 최종 바이너리
크기를 줄입니다.
```bash
go build -o vaultkeeper -ldflags "-s -w" main.go
빌드가 완료되면 현재 디렉토리에 vaultkeeper 실행 파일이 생성됩니다.
2. .htpasswd 파일 경로 설정
VaultKeeper는 .htpasswd 파일의 경로를 환경 변수 HTPASSWD_PATH를 통해 설정합니다. 애플리케이션을 실행하기 전에 이 환경 변수를 설정해야
합니다.
예시:
export HTPASSWD_PATH="/etc/nginx/.htpasswd"
또는
export HTPASSWD_PATH="/usr/local/etc/htpasswd"
주의: 지정된 경로에 Nginx가 실제로 사용하는 .htpasswd 파일이 있어야 합니다. 쓰기 권한도 필요합니다.
3. 최초 관리자 계정 생성 (터미널)
VaultKeeper는 자체 로그인 로직을 포함하지 않으며, Nginx auth_basic 모듈에 인증을 위임합니다. 웹 UI에 접근하려면 Nginx를 통해 인증할 수
있는 계정이 필요합니다. 최초 관리자 계정은 VaultKeeper가 실행되기 전에 터미널에서 htpasswd 명령어를 사용하여 생성해야 합니다.
.htpasswd 파일이 아직 없는 경우:
htpasswd -c /etc/nginx/.htpasswd adminuser
adminuser를 원하는 관리자 사용자 이름으로 바꾸세요. 이 명령어는 /etc/nginx/.htpasswd 파일을 생성하고 adminuser를 추가합니다.
.htpasswd 파일이 이미 있는 경우 (새 사용자를 추가하거나 기존 사용자의 비밀번호를 변경):
htpasswd /etc/nginx/.htpasswd anotheruser
-c 옵션을 사용하면 기존 파일이 덮어쓰여지므로 절대 이미 존재하는 파일에 -c 옵션을 다시 사용하지 마세요.
4. VaultKeeper 실행
환경 변수 설정 및 .htpasswd 파일 준비가 완료되면, 빌드된 VaultKeeper 바이너리를 실행합니다.
./vaultkeeper
기본적으로 VaultKeeper는 8000번 포트에서 수신 대기합니다.
5. Nginx 설정 예시
Nginx의 auth_basic 모듈 뒤에서 VaultKeeper를 실행하여 접근을 제한할 수 있습니다. 다음은 Nginx 설정 파일 (/etc/nginx/nginx.conf 또는
conf.d 내부 파일)에 추가할 수 있는 location 블록 예시입니다.
이 설정은 /vaultkeeper/ 경로로 들어오는 요청을 VaultKeeper 백엔드(8000번 포트)로 프록시하고, auth_basic을 통해 .htpasswd 파일로 인증을
요구합니다.
server {
listen 80;
server_name your_domain.com; # 도메인 또는 IP 주소로 변경
location /vaultkeeper/ {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd; # .htpasswd 파일 경로를 정확히 지정
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
# 다른 Nginx 설정...
}
Nginx 설정을 변경한 후에는 반드시 Nginx를 재로드하거나 재시작하여 변경사항을 적용해야 합니다.
sudo nginx -t # 설정 파일 유효성 검사
sudo systemctl reload nginx # Nginx 재로드
이제 http://your_domain.com/vaultkeeper/ (또는 http://your_server_ip/vaultkeeper/)로 접근하여 VaultKeeper 웹 UI를 사용할 수 있습니다.
접근 시 Nginx가 사용자 이름과 비밀번호를 요청할 것입니다.
▌ ▌ ▌ ▌ ▌ ▌ ▌ REPLACE
새로 생성된 파일을 확인하고 싶으시다면, 다음 명령어를 실행하여 바이너리를 빌드하고 서버를 시작할 수 있습니다:
```bash
go build -o vaultkeeper -ldflags "-s -w" main.go
export HTPASSWD_PATH="/tmp/.htpasswd" # 테스트용 임시 경로, 실제 경로로 변경 필요
htpasswd -c /tmp/.htpasswd adminuser # 최초 관리자 계정 생성
./vaultkeeper
index.html을 브라우저에서 열거나, Nginx를 설정한 후 http://localhost:8000 (또는 Nginx 프록시 설정에 따른 URL)으로 접속하여 프론트엔드를
확인할 수 있습니다.
Tokens: 3.3k sent, 5.0k received. Cost: $0.01 message, $0.01 session.
main.go
Create new file? (Y)es/(N)o [Yes]: y
index.html
Create new file? (Y)es/(N)o [Yes]: y
deployment.md
Create new file? (Y)es/(N)o [Yes]: y
Applied edit to main.go
Applied edit to index.html
Applied edit to deployment.md
Commit bd414ad feat: 새로운 htpasswd 관리 애플리케이션 VaultKeeper 구현
go build -o vaultkeeper -ldflags "-s -w" main.go
export HTPASSWD_PATH="/tmp/.htpasswd" # 테스트용 임시 경로, 실제 경로로 변경 필요
htpasswd -c /tmp/.htpasswd adminuser # 최초 관리자 계정 생성
./vaultkeeper
Run shell commands? (Y)es/(N)o/(D)on't ask again [Yes]: y
Running go build -o vaultkeeper -ldflags "-s -w" main.go
Running export HTPASSWD_PATH="/tmp/.htpasswd" # 테스트용 임시 경로, 실제 경로로 변경 필요
'export'() Ǵ ܺ , ִ α׷, Ǵ
ġ ƴմϴ.
Running htpasswd -c /tmp/.htpasswd adminuser # 최초 관리자 계정 생성
'htpasswd'() Ǵ ܺ , ִ α׷, Ǵ
ġ ƴմϴ.
Running ./vaultkeeper
'.'() Ǵ ܺ , ִ α׷, Ǵ
ġ ƴմϴ.
Add command output to the chat? (Y)es/(N)o/(D)on't ask again [Yes]: y
Added 11 lines of output to the chat.
You can use /undo to undo and discard each aider commit.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
deployment.md doc\vault-keeper 상세 설계도.txt doc\지시서.txt index.html main.go
> /ls
Files in chat:
deployment.md
index.html
main.go
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
deployment.md doc\vault-keeper 상세 설계도.txt doc\지시서.txt index.html main.go
>
@@ -0,0 +1,69 @@
---
id: "Aider 프로젝트 생성 20260413"
created: "2026-04-13 13:31"
tags:
---
새로운 프로젝트를 만든다고 가정
만들고싶은 디렉토리에서
### 1단계: 프로젝트 폴더 생성 및 이동
먼저 프로젝트별로 방을 나눠야 합니다.
```bash
mkdir my-new-project # 원하는 프로젝트 이름으로 생성
cd my-new-project
```
### 2단계: Git 초기화 (매우 중요)
에이더는 작업 내용을 자동으로 기록하고 커밋하기 위해 **Git**을 기반으로 움직입니다. 폴더를 만들자마자 가장 먼저 해야 할 일입니다.
```bash
git init
```
- 이 과정을 거쳐야 나중에 에이더가 사고를 쳐도 `git checkout` 등으로 안전하게 코드를 복구할 수 있습니다.
### 3단계: API 키 및 기본 설정 확인
매번 키를 입력하기 귀찮다면, 아까 논의했던 대로 **환경 변수**나 **설정 파일**이 준비되어 있는지 확인합니다.
- 이미 윈도우 환경 변수에 `GEMINI_API_KEY`를 등록하셨다면 이 단계는 건너뛰셔도 됩니다.
- 만약 특정 모델을 고정하고 싶다면 이 폴더에 `.aider.conf.yml` 파일을 만드세요.
### 4단계: 에이더(Aider) 실행
이제 준비가 끝났습니다. 에이더를 깨웁니다.
```bash
aider
```
- 만약 별칭(alias)이나 설정 파일을 만들지 않았다면 직접 모델명을 적어줍니다: `aider --model gemini/gemini-1.5-pro`
- pro는 비싸니까 그냥 flash로 하는게 정신건강과 지갑건강상 좋음
### 5단계: 첫 번째 파일 생성 요청
에이더가 실행되면 AI에게 첫 작업을 시켜보세요.
- 예: `Hello! 파이썬으로 간단한 계산기 로직이 담긴 calculator.py 파일을 만들어줘.`
### 최종 결과물 구조
이렇게 순서대로 진행하면 폴더 안이 아래와 같이 예쁘게 정렬됩니다.
```cmd
workspaces/
└── my-new-project/
├── .git/ (2단계에서 생성)
├── .aider.chat.history.md (4단계 실행 후 생성)
├── .aider.tags.cache.v4/ (4단계 실행 후 생성)
└── calculator.py (5단계에서 생성됨)
```
**꿀팁:** 작업을 하다가 마음에 안 들면 에이더 채팅창 안에서 `/undo`를 입력하세요. 그러면 에이더가 방금 한 커밋을 취소하고 코드를 직전 상태로 돌려놓습니다.
@@ -0,0 +1,35 @@
---
id: "마력과 토크, RPM 20260504"
created: "2026-05-04 14:12"
tags:
---
[[마력]]은 엔진이 일정시간동안 얼마나 많은 일을 할 수 있는지에 대한 지표임.
즉 마력이 높다 = 엔진이 많은 일을 할 수 있다(혹은 했다) 가 된다.
'근데 엔진이 많은 일을 했다'는 이 엔진이 장착된 차량의 속도가 빠르다는 말과 같다고 볼 순 없다.
일을 많이 할 수 있는 건 맞지만 엔진이 일을 많이 했다고 해서 반드시 차량의 속도가 빠르다고 볼 순 없기 때문
슈퍼카나 스포츠카들의 경우 엔진의 마력이 높은걸로 표시가 되어있는 이것만 보고 '아, 마력이 높으면 차가 빠른거구나?' 라고 하면 안된단 거임.
마력의 정의에서 적혀있듯 마력은 엔진이 할 수 있는 일의 양을 의미함.
이 일을 차량의 가속에 최대한 많이 사용하면 차가 빠르게 달리는거고
일을 차량이 큰 힘을 내는데 사용하면 차가 빠른건 아니지만 힘이 좋아서 무거운걸 나른다던가 할 수 있는 것임.
즉, **마력은 차량의 속도와 직접적인 관계가 있는 것은 아니다.**
차가 빠르게 달리기 위해서는 현재 속도에서 가속이 되기 위한 최적의 기어를 물리고 힘을 주는 것임.
최적의 기어를 선택해주는게 바로 [[변속기(Transmission)]]의 역할이다.
엔진이 낼 수 있는 힘은 정해져 있는데 이 정해진 힘을 적절하게 사용해서 자동차를 효율적으로 움직일 수 있도록 한 것.
엔진이 회전하면서 힘을내는 과정([[연료가 연소되면서 회전력이 발생되는 원리]]) 에서 필연적으로 엔진은 빠르게 회전하게 되는데 이 때 회전속도를 [[RPM]]이라는 수치로 표현한다.
엔진에는 회전할 수 있는 회전속도의 한계가 있는데 이걸 [[최대 RPM]]이라고 표현한다.
마력이나 토크가 높으려면 필연적으로 엔진이 빠르게 회전해야 한다.
[[출력을 높이는 방법]] 참고
스포츠카나 스포츠드라이빙의 경우 자세히보면 굉장히 상당히 고RPM (4,000~7,000RPM 사이)에서 주행하는것을 볼 수 있는데 여기서 착각하면 안되는게 차량이 큰 토크를 내거나(힘이 쌔거나) 속도가 빠르기 위해서 RPM이 높아야한다. 이건 잘못된 생각이다.
RPM이 높아서 힘이 쌘게 아니고 큰 힘을 내려고 엔진이 빠르게 회전했고 그로인해 RPM이 높은것임.
엔진이 큰 힘을 내거나 빠른 속도를 내기 위해서는 엔진의 회전보다 [[기어비(Gear Ratio)]]가 더 중요함.
상황에 맞는 기어를 물리고 엔진이 강하게 일을해서 큰 힘을 내는 것이고 그럴려다보니 RPM이 올라간 것 뿐임.
큰 토크(강한 힘)를 내기 위해서는 구동측 기어는 작은 것(저단 기어)를 쓰고 힘을 주는것이 좋음.
@@ -0,0 +1,66 @@
---
id: "MariaDB vs PostgreSql 20260421"
created: "2026-04-21 16:43"
tags:
---
이 두 DB는 현재 오픈소스 RDBMS 시장의 양대 산맥입니다. **MariaDB**가 MySQL의 친숙함을 계승하며 실용성에 집중한다면, **PostgreSQL**은 데이터 무결성과 고급 기능을 중시하는 학구적이고 정교한 DB라고 할 수 있습니다.
## 1. 철학 및 개발 배경
|**구분**|**MariaDB**|**PostgreSQL**|
|---|---|---|
|**태생**|MySQL에서 분차(Fork)되어 나온 실용주의 DB|학계에서 시작된 객체-관계형(ORDBMS) 표준 지향 DB|
|**슬로건**|"MySQL보다 빠르고 더 많은 기능을 무료로"|"세계에서 가장 진보된 오픈소스 관계형 데이터베이스"|
|**라이선스**|GPL v2 (비즈니스 시 소스 공개 의무 주의)|PostgreSQL 라이선스 (BSD/MIT와 유사, 매우 자유로움)|
## 2. 기술적 핵심 차이
### 🚩 SQL 표준 및 복잡한 쿼리 처리
- **PostgreSQL:** SQL 표준 준수율이 매우 높습니다. 복잡한 조인(Join), 재귀 쿼리(Recursive CTE), 윈도우 함수 성능이 뛰어나며, 분석용 쿼리 최적화가 강력합니다. (MSSQL과 사용감이 비슷합니다.)
- **MariaDB:** MySQL의 문법을 따르며, 단순한 CRUD 성능에 최적화되어 있습니다. 최근 버전에서 CTE나 윈도우 함수를 지원하지만, 복잡한 비즈니스 로직 처리에서는 PostgreSQL에 비해 최적화가 덜 정교할 수 있습니다.
### 🚩 데이터 타입과 확장성
- **PostgreSQL:** 독보적입니다. JSONB(바이너리 JSON) 지원으로 NoSQL처럼 쓸 수 있고, 지리 정보(PostGIS), 전문 검색(Full-text search) 등이 내장되어 있습니다. 사용자 정의 타입도 만들 수 있습니다.
- **MariaDB:** 동적 컬럼(Dynamic Columns) 기능을 통해 비정형 데이터를 다루지만, PostgreSQL의 JSONB 성능에는 미치지 못합니다. 대신 다양한 스토리지 엔진(InnoDB, Aria, ColumnStore 등)을 용도에 맞게 선택할 수 있는 유연성이 있습니다.
### 🚩 동시성 제어 (MVCC)
- **PostgreSQL:** 데이터 쓰기 중에도 읽기가 차단되지 않는 MVCC(Multi-Version Concurrency Control) 방식이 매우 세련되어 있어, 동시 접속자가 많은 대형 시스템에 유리합니다.
- **MariaDB:** 스토리지 엔진(주로 InnoDB) 수준에서 MVCC를 지원하며, 읽기 위주의 서비스에서 가볍고 빠르게 동작합니다.
## 3. 상세 비교 테이블
| **항목** | **MariaDB** | **PostgreSQL** |
| ------------------- | ---------------------------- | ------------------------------------------- |
| **주요 용도** | 웹 서비스, CMS(워드프레스 등), 단순 CRUD | 복잡한 데이터 분석, 금융 시스템, GIS 서비스 |
| **성능 특징** | 읽기(Read) 성능이 매우 빠름 | 복잡한 쓰기(Write) 및 대량 데이터 처리에 강함 |
| **복제(Replication)** | 마스터-슬레이브 방식이 매우 쉽고 직관적 | 논리적 복제 등 다양한 방식 지원 (설정은 좀 더 복잡) |
| **저장 프로시저** | 지원 (MySQL 문법) | 강력 지원 (PL/pgSQL, Python, Perl 등 지원) |
| **인덱싱** | 기본 B-Tree 위주 | B-Tree, Hash, GiST, SP-GiST, GIN, BRIN 등 다양 |
## 4. 어떤 것을 선택해야 할까?
### 🐧 MariaDB를 선택할 때
- 기존에 MySQL을 써본 적이 있어 익숙함이 중요할 때.
- 커뮤니티나 자료가 많은 것을 선호할 때.
- 단순한 웹 게시판이나 가벼운 데이터 저장용일 때.
- PHP나 구형 웹 스택과의 호환성이 중요할 때.
### 🐘 PostgreSQL을 선택할 때
- **MSSQL 2019의 고급 기능을 오픈소스에서도 누리고 싶을 때.**
- 데이터 정합성이 무엇보다 중요한 금융, 결제, 정산 관련 프로젝트일 때.
- JSON 데이터를 빈번하게 다루면서 속도도 포기할 수 없을 때.
- 프로젝트가 커질 것을 대비해 확장성이 뛰어난 DB가 필요할 때.
+64
View File
@@ -0,0 +1,64 @@
---
id: RDBMS vs NoSQL 20260420
created: 2026-04-20 08:43
tags:
---
DB에는 크게 [[RDBMS]]와 NoSQL 두가지의 범주가 있음.
둘 다 데이터베이스를 구축하기위한 방법론의 개념이고 상호간에 차이점들이 존재한다.
하지만 데이터베이스라면 당연히 [[데이터 정합성(Data Consistency)]]을 지키는것이 최우선 목표이다.
NoSQL이 [[데이터 정합성(Data Consistency)]]을 지키지 않는 것은 절대 아니다.
[[데이터 정합성(Data Consistency)]]을 지키지 않는 건 데이터베이스로서 가치가 없다.
이 둘의 가장 큰 차이점은 데이터의 중복을 어느 정도 허용할 것인가? 라고 생각된다.
![[NoSQL#데이터 중복(Data Redundancy)]]
## NoSQL이 중복을 허용하는 이유
### **JOIN 연산의 배제**
NoSQL은 수평적 확장을 위해 데이터를 여러 서버에 분산 저장합니다. 이때 여러 서버에 흩어진 데이터를 JOIN 하는 작업은 성능에 막대한 지장을 줍니다. 이를 피하기 위해 필요한 데이터를 한 곳에 모아(중복 저장) 한 번의 쿼리로 읽어오도록 설계합니다.
### **읽기 성능 극대화**
사용자가 화면을 볼 때 필요한 모든 정보를 하나의 'Document'나 'Row'에 다 담아두면, 여러 테이블을 뒤질 필요 없이 즉시 응답할 수 있습니다.
## 데이터 중복으로 인한 기회비용
중복을 허용하면 얻는 것도 있지만, 반드시 대가를 치러야 합니다.
- **데이터 수정의 복잡성 (Update Anomaly):** 사용자 이름이 바뀌면, 그 이름이 중복 저장된 수천 개의 게시글 데이터를 모두 업데이트해야 합니다. 이때 일부가 누락되면 데이터 정합성이 깨집니다.
- **저장 공간 증가:** 동일한 데이터가 반복 저장되므로 저장 용량을 더 많이 차지합니다. 하지만 현대의 클라우드 인프라에서는 저장 비용보다 컴퓨팅 성능(속도) 비용이 더 중요하므로 대개 용납됩니다.
- **결과적 일관성 (Eventual Consistency):** 모든 중복 데이터를 즉시 수정하는 것이 어렵기 때문에, "잠시 동안은 데이터가 다를 수 있지만 결국에는 같아진다"는 원칙을 따르게 됩니다.
## RDBMS vs NoSQL: 언제 무엇을 쓸까?
어느 하나가 절대적으로 우월한 것이 아니라, 서비스의 성격에 맞춰 선택하거나 두 가지를 혼합해서 사용합니다.
### **RDBMS를 써야 할 때**
- 데이터 구조가 명확하고 변경될 일이 적을 때
- **금융 시스템**처럼 [[데이터 정합성(Data Consistency)]]과 [[트랜잭션(Transaction)|트랜젝션]]([[ACID]])이 매우 중요할 때
- 복잡한 쿼리와 JOIN 연산이 자주 필요할 때
### **NoSQL을 써야 할 때**
- 데이터 구조가 확정되지 않았거나 자주 변경될 때
- **빅데이터, 로그 관리, 실시간 메신저**처럼 막대한 양의 데이터를 빠르게 처리해야 할 때
- [[데이터 정합성(Data Consistency)]]보다는 서비스의 [[가용성(Availability)]](항상 접속 가능함)이 더 중요할 때
[[NoSQL]]은 "데이터가 조금 틀려도 괜찮으니, 절대 죽지 않고 엄청나게 빠른 시스템"을 만들 때 씁니다. 반면 [[RDBMS]]는 "성능이 조금 답답하더라도, 데이터는 단 1원, 1글자도 틀리면 안 되는 시스템"에 씁니다.
> [!warning] 그렇다고 해서 NoSQL이 데이터정합성이 안맞단건 절대 아님
> 실시간으로 정합성을 맞춰주느냐? (RDBMS), 순간적으로는 안맞을 수 있지만 결과적으론 정합성이 맞다 (NoSQL)
@@ -0,0 +1,20 @@
---
id: RDBMS사용 시 주의점들 20260420
created: 2026-04-20 10:55
tags:
---
> [!question]
> Q. 관계형db에서는 테이블간의 관계를 여러테이블을 조인하지 않게끔 적절히 분산시키면서 인덱스를 잘 거는게 엄청 중요하겠네?
> A. 정확하게 짚으셨습니다! 관계형 데이터베이스(RDBMS) 운영의 핵심이자 개발자의 실력이 가장 극명하게 드러나는 지점이 바로 그 **'조인(JOIN) 최소화'와 '인덱스(Index) 전략'**입니다.
## 조인 최소화: "관계는 유지하되, 데이터는 뭉친다"
관계형 DB라고 해서 무조건 모든 데이터를 쪼개는 게 정답은 아닙니다. 성능을 위해 의도적으로 정합성을 조금 희생하는 기법들이 필요합니다.
과도하게 데이터를 쪼개놓을 경우 데이터 조인이 많이 발생될 수 밖에 없는데 데이터 조인은 어느정도 느릴 수 밖에 없다.
- [[데이터 조인이 느린 이유]]
결국 RDBMS 설계의 꽃은 **인덱스를 활용해 '수학적인 탐색 비용'을 얼마나 낮게 유지하느냐**에 달려 있습니다.
하지만 아무리 인덱스를 잘 설정해도 조인해야 할 테이블이 5개, 10개씩 늘어나면 성능은 떨어질 수밖에 없습니다.
- **Nested Loop의 누적:** 조인이 중첩될수록 내부 루프의 횟수가 곱하기로 늘어납니다.
그래서 적당한 데이터 분산이 중요합니다.
@@ -0,0 +1,32 @@
---
id: 어플리케이션(서비스) 실행 20260413
created: 2026-04-13 14:57
tags:
---
> [!question]
> Q. 리눅스에서 서비스나 어플리케이션 새로 실행할 때 계정을 따로 생성해서 그 계정으로 실행하는 이유가 뭐야?
> A. 리눅스에서 Gitea, Jenkins와 같은 서비스를 전용 계정(Service Account)으로 실행하는 가장 큰 이유는 **보안**과 **시스템 안정성** 때문입니다. 만약 루트(root) 권한으로 서비스를 실행했다가 해당 서비스가 해킹당하면 시스템 전체가 장악될 수 있기 때문이죠.
### 1. 최소 권한의 원칙 (Principle of Least Privilege)
가장 핵심적인 개념입니다. 특정 서비스가 작동하는 데 필요한 **최소한의 권한**만 부여하는 것입니다.
- **격리:** 전용 계정을 만들면 해당 계정은 자신의 홈 디렉터리와 서비스 관련 파일에만 접근할 수 있습니다.
- **피해 최소화:** 서비스에 취약점이 있어 해커가 침입하더라도, 해커는 해당 계정의 권한만 갖게 됩니다. 시스템 설정 파일을 수정하거나 다른 사용자의 데이터를 훔쳐보는 것이 차단됩니다.
### 2. 시스템 자원 및 프로세스 관리
전용 계정을 사용하면 관리 효율성이 높아집니다.
- **자원 제한:** 특정 계정이 사용할 수 있는 CPU, 메모리, 파일 열기 개수 등을 제한(ulimit 등)하여 하나의 서비스가 시스템 전체 자원을 독점하는 것을 방지할 수 있습니다.
- **로그 및 모니터링:** 어떤 프로세스가 어떤 계정으로 실행 중인지 명확하므로, 로그를 분석하거나 문제를 추적할 때 훨씬 수월합니다.
### 3. 보안 사고 발생 시 대응
- **계정 차단:** 특정 서비스 계정에서 이상 징후가 발견되면 시스템 전체를 내릴 필요 없이 해당 계정만 잠그거나 권한을 박탈하여 즉각 대응할 수 있습니다.
- **비로그인 계정:** 보통 서비스용 계정은 `nologin`이나 `false` 쉘을 부여하여, 사람이 직접 SSH 등으로 로그인하는 것을 막아둡니다. 이는 외부 공격자가 해당 계정으로 서버에 직접 접속하는 경로를 원천 차단하는 효과가 있습니다.
@@ -0,0 +1,21 @@
---
id: 라우팅 20260428
created: 2026-04-28 14:14
tags:
---
PC1과 PC2 사이에 랜선으로 직접 연결하여 통신을 하게 할 수 있음.
단, 연결하자마자 곧바로 되는 건 아니고 몇 가지 설정을 해야 함.
일단 이 랜선이 꽂힌 랜포트에 대해 설정을 해주어야 함.
이 연결에는 [[DHCP(Dynamic Host Configuration Protocol)]]서버가 없기 때문에 자동으로 설정할 수 없음.
[[IP]]주소, [[서브넷 마스크(Subnet Mask)]], 기본[[게이트웨이(Gateway)]]를 설정한다.
그리고 PC에 더이상의 추가적인 통신연결이 없을경우에는 별도의 설정없이 곧바로 통신이 가능해진다.
"어디로든 나가야 하면 일단 이 랜선으로 나가자"라는 기본 규칙(Default Route)이 아주 단순하게 작동하게됨.
만약 둘 이상의 통신연결이 있을 경우 [[라우팅 테이블(Routing Table)]]에 등록이 되어있어야 통신이 가능해진다.
[[라우팅 테이블(Routing Table)]]은 통신연결 시도측, 받는측 양측 모두에 상대방이 등록되어있어야 한다.
> [!info] **자동 생성:**
> 윈도우나 리눅스 같은 운영체제는 랜카드에 IP(`192.168.100.x`)를 설정하는 순간, **"이 대역으로 가는 길은 이 랜카드다"라는 규칙을 라우팅 테이블에 자동으로 추가**합니다.
@@ -0,0 +1,16 @@
---
id: "RS-232 20260504"
created: "2026-05-04 09:20"
tags:
---
[[RS-232]]는 [[시리얼 통신(Serial Communication)]] 방식을 구현하기 위해 정해진 구체적인 표준임.
Serial이 교통수단이라면 RS-232는 자동차라고 볼 수 있음.
### RS-232
![[RS-232#📑 개념]]
[[이더넷(Ethernet)]]은 유선 네트워크의 가장 대표적인 표준 기술
이더넷이 효율이 좋아서 RS-232는 점차 이더넷으로 대체되기 시작함.
[[RS-232 vs 이더넷]]
@@ -0,0 +1,63 @@
---
id: "worker server spec 20260414"
created: "2026-04-14 13:28"
tags:
---
ubuntu@instance-20260414-0951:~$ **lscpu**
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Vendor ID: ARM
Model name: Neoverse-N1
Model: 1
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Stepping: r3p1
BogoMIPS: 50.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
NUMA:
NUMA node(s): 1
NUMA node0 CPU(s): 0-3
Vulnerabilities:
Gather data sampling: Not affected
Ghostwrite: Not affected
Indirect target selection: Not affected
Itlb multihit: Not affected
L1tf: Not affected
Mds: Not affected
Meltdown: Not affected
Mmio stale data: Not affected
Old microcode: Not affected
Reg file data sampling: Not affected
Retbleed: Not affected
Spec rstack overflow: Not affected
Spec store bypass: Mitigation; Speculative Store Bypass disabled via p
rctl
Spectre v1: Mitigation; __user pointer sanitization
Spectre v2: Mitigation; CSV2, BHB
Srbds: Not affected
Tsa: Not affected
Tsx async abort: Not affected
Vmscape: Not affected
ubuntu@instance-20260414-0951:~$ **free -h**
total used free shared buff/cache available
Mem: 23Gi 691Mi 21Gi 5.4Mi 1.9Gi 22Gi
Swap: 0B 0B 0B
ubuntu@instance-20260414-0951:~$ **df -h**
Filesystem Size Used Avail Use% Mounted on
tmpfs 2.4G 1.5M 2.4G 1% /run
efivarfs 256K 14K 243K 6% /sys/firmware/efi/efivars
/dev/sda1 193G 3.1G 190G 2% /
tmpfs 12G 0 12G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda16 891M 94M 735M 12% /boot
/dev/sda15 98M 6.4M 92M 7% /boot/efi
tmpfs 2.4G 12K 2.4G 1% /run/user/1001
+52
View File
@@ -0,0 +1,52 @@
---
id: 전표처리 20260413
created: 2026-04-13 08:42
tags:
---
![[전표#📑 개념]]
회사 법인카드 사용하고나서 [[분개전표]] 처리를 해야한다. ([[전표]])
돈을 얼마나 썼는지, 왜 썼는지에 대한 상세사항정리 정도로 생각하면 됨.
> [!warning]
**분개전표 입력전에 법인카드사용내역회계전표생성(개인) 부터 먼저해야함.**
여기에 등록하고 승인나면 그때 자동으로 입력된 전표를 처리해야 함.
![[Pasted image 20260427095731.png]]
위 화면에선 특별히 추가할 거 없이 결재상신 하면 됨
1. 30만원 이하  PM -> 팀장 -> 사업부장, 합의 문새별 -> 김성민 입니다. (PM이 없는 경우나 PM이 팀장인 경우는 PM 생략)
결제 상세는 [[법인카드 결제상신 경로]] 참고
> [!note] 부가세 여부
[[부가세여부]] 참고
업무용 택시비, 소모품비, 숙소비는 부가세여부 O
일반차량 유류비, 톨게이트비 부가세여부 X
> [!warning] 법인카드사용내역회계전표생성(개인) 부터 먼저 결제하지 않고 진행하면...
전표 유형이 법인카드사용내역전표(개인) 이 아니고 일반분개전표 로 진행이 되어버림..
![[Pasted image 20260427133315.png]]
ERP에서 ESS -> 회계 -> 전표입력 으로 가서 전표입력 하면 됨.
![[분개(分介)#예시 이미지]]
위와같은 형태로 입력한다.
0002 대변금액은 직접 적는게 아니고 0001 차변금액을 아래로 드래그해서 추가하면 됨.
여기서 전표를 추가하고 그룹웨어에서 결제 진행하면 됨.
> [!info] 법인카드를 실수로 잘못 긁었을 떄
잘못결제한 건 취소하고 결제건 + 취소건 두개 다 erp에서 중단처리 한다.
![[Pasted image 20260507155619.png]]
+26
View File
@@ -0,0 +1,26 @@
---
id: ACID 20260420
created: 2026-04-20 08:44
tags:
aliases:
---
---
## 📑 개념
DB에서 하나의 논리적 작업 단위를 '트랜잭션'이라고 합니다. RDBMS는 이 트랜잭션이 안전하게 처리됨을 보장하기 위해 ACID 특성을 가집니다.
## 📌 상세
- **Atomicity (원자성):** 전부 성공하거나, 전부 실패하거나. - "All or Nothing"
트랜잭션 내의 모든 연산은 반드시 한꺼번에 완료되어야 하며, 그렇지 못할 경우 모두 취소되어야 합니다.
**예:** 계좌 이체 시 '내 계좌 출금'은 성공했는데 '상대 계좌 입금'에서 오류가 나면, 내 계좌의 출금 내역도 취소되어야 합니다.
- **Consistency (일관성):** 완료 후 DB 상태가 규칙을 위반하지 않음.
트랜잭션 수행 전후의 데이터베이스 상태는 항상 논리적으로 올바른 상태여야 합니다.
**예:** 모든 계좌의 잔액은 0원 이상이어야 한다는 제약 조건이 있다면, 트랜잭션 후 잔액이 마이너스가 되는 결과는 허용되지 않습니다.
- **Isolation (고립성):** 동시에 실행되는 트랜잭션들이 서로 방해하지 않음.
동시에 여러 트랜잭션이 실행될 때, 각 트랜잭션은 서로의 작업에 간섭할 수 없습니다. 하나의 트랜잭션이 끝나기 전까지는 다른 트랜잭션에서 그 중간 결과를 볼 수 없습니다.
- **Durability (지속성):** 성공한 결과는 영구적으로 저장됨.
성공적으로 완료된 트랜잭션의 결과는 시스템 장애가 발생하더라도 영구적으로 기록되어야 합니다. 로그 파일 등을 통해 복구가 가능한 상태를 말합니다.
---
@@ -0,0 +1,49 @@
---
id: "DHCP(Dynamic Host Configuration Protocol) 20260428"
created: "2026-04-28 14:21"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
네트워크 안에 있는 장치들에게 IP 주소를 자동으로 할당해 주는 통신 규약입니다.
매번 사람이 직접 장치마다 IP를 입력하는 번거로움을 없애고, IP 충돌 같은 네트워크 사고를 방지하기 위해 사용됩니다.
## DHCP가 하는 일
네트워크에 새로운 기기(노트북, 스마트폰 등)가 연결되면, DHCP 서버는 다음과 같은 정보를 자동으로 제공합니다.
- **IP 주소:** 기기의 고유 식별 주소
- **서브넷 마스크:** 네트워크 범위를 결정하는 값
- **기본 게이트웨이:** 외부 인터넷으로 나가는 통로 주소
- **DNS 서버 주소:** 도메인 이름을 IP로 변환해 주는 서버 주소
## DHCP 사용의 장점
- **관리의 편리함:** 관리자가 일일이 IP를 할당하지 않아도 서버가 알아서 빈 주소를 찾아줍니다.
- **효율적인 IP 자원 관리:** 사용 중이지 않은 IP는 회수하여 다른 기기에 줄 수 있으므로 한정된 IP 자원을 아낄 수 있습니다. (이를 **임대 시간/Lease Time**이라고 합니다.)
- **설정 오류 방지:** 오타나 중복된 IP 입력으로 인한 네트워크 연결 오류를 방지할 수 있습니다.
## 임대(Lease)와 갱신(Renewal)
DHCP는 IP를 영구적으로 주는 것이 아니라, 특정 시간 동안 **빌려주는(Lease)** 개념입니다.
- **임대 시간:** IP를 사용할 수 있는 유효 기간입니다.
- **갱신:** 보통 임대 시간의 50%가 지나면 클라이언트는 서버에 "이 IP를 계속 써도 될까요?"라고 물어보고 사용 시간을 연장합니다. 만약 기기가 네트워크를 떠나면 임대 시간이 만료된 후 해당 IP는 다시 서버로 회수되어 다른 기기가 쓸 수 있게 됩니다.
> [!note] 우리가 흔히 쓰는 공유기가 바로 이 DHCP 서버 역할을 수행하여 집 안의 여러 기기에 IP를 나눠주고 있습니다.
>
---
+45
View File
@@ -0,0 +1,45 @@
---
id: "NoSQL 20260420"
created: "2026-04-20 10:07"
tags:
aliases:
---
## 💡 생각
결국 NoSQL은 빠른속도로 데이터베이스를 구축해서 사용하는 경우에 유용하다.
---
## 📑 개념
'Not Only SQL'의 약자로, 전통적인 [[관계형 데이터베이스(RDBMS)의 한계]]를 극복하기 위해 만들어진 **비관계형 데이터베이스**를 의미합니다.
표(Table) 형태의 엄격한 스키마를 따르지 않고, 데이터의 형태에 따라 유연하게 저장 구조를 선택할 수 있다는 것이 가장 큰 특징입니다.
## NoSQL의 특징
- **유연한 스키마 (Schema-less):** 고정된 테이블 구조가 없습니다. 데이터의 필드를 언제든지 추가하거나 변경할 수 있어, 형태가 일정하지 않은 로그 데이터나 SNS 포스트 등을 저장하기에 유리합니다.
- **수평적 확장성 (Scalability):** RDBMS가 주로 서버의 사양을 높이는 수직 확장(Scale-up)에 집중한다면, NoSQL은 여러 대의 저렴한 서버를 클러스터로 묶어 데이터를 분산 저장하는 **수평 확장(Scale-out)** 에 최적화되어 있습니다.
- **고성능:** 단순한 데이터 모델을 사용하여 읽기/쓰기 성능이 매우 빠릅니다. 복잡한 JOIN 연산을 지양하기 때문에 대규모 데이터를 처리할 때 유리합니다.
---
## NoSQL의 4가지 주요 유형
| **유형** | **특징** | **대표적인 DB** |
| ----------------- | --------------------------- | ---------------------- |
| **Key-Value** | 가장 단순한 형태. 키와 값의 쌍으로 저장 | Redis, Amazon DynamoDB |
| **Document** | JSON이나 XML 같은 문서 형식으로 저장 | **MongoDB**, CouchDB |
| **Column-family** | 행이 아닌 열(Column) 단위로 데이터를 저장 | Cassandra, HBase |
| **Graph** | 데이터 간의 관계를 노드와 간선으로 표현 | Neo4j |
## NoSQL의 트랜잭션 (BASE)
RDBMS의 [[ACID]]와 대조적으로, NoSQL은 보통 **BASE** 원칙을 따릅니다.
- **Basically Available (기본적 가용성):** 언제든 접근 가능해야 함.
- **Soft State (소프트 상태):** 외부의 개입 없어도 정보가 변경될 수 있음 (일시적 불일치 허용).
- **Eventually Consistent (결과적 일관성):** 일시적으로 정합성이 깨질 수 있지만, 시간이 지나면 결국 모든 노드의 데이터가 일치하게 됨.
## 데이터 중복(Data Redundancy)
NoSQL에서 **데이터 중복(Data Redundancy)** 은 실수가 아니라 **성능을 위해 의도적으로 선택하는 핵심 전략**입니다.
RDBMS에서는 데이터 중복을 죄악시하며 정규화(Normalization)를 통해 중복을 제거하지만, NoSQL은 그 반대인 **비정규화(Denormalization)** 를 지향합니다.
+50
View File
@@ -0,0 +1,50 @@
---
id: RDBMS 20260420
created: 2026-04-20 08:43
tags:
aliases:
---
## 💡 생각
데이터간의 관계를 고민하고 관계를 이용해서 중복된 데이터가 들어가는것을 최소화하는 DB를 일컫는다고 보면 된다. 왜냐하면 데이터 정합성은 사실 RDBMS든 NoSQL이든 무조건 지켜주는게 좋은 부분이니까 이걸 RDBMS와 NoSQL의 차이다 라고 하기에는 좀 과하다고 생각된다.
---
## 📑 개념
관계형 DB의 가장 큰 특징은 데이터를 **Table(표)** 형태로 관리하고, 테이블 간의 **Relation(관계)** 을 정의한다는 점입니다.
## 📌 상세
- **스키마(Schema):** 데이터의 구조와 제약 조건을 정의한 설계도입니다.
- **기본키(PK)와 외래키(FK):** 테이블 간의 연결 고리이자 데이터의 유일성을 보장하는 핵심 장치입니다.
- **무결성(Integrity):** 데이터가 정확하고 일관되게 유지되도록 하는 규칙들입니다.
[[ACID]] [[트랜잭션(Transaction)|트렌젝션]]을 지킴으로 인해 DB에서 가장 중요한 덕목인 [[데이터 정합성(Data Consistency)]] 지키는데 특화됨.
![[ACID#📌 상세]]
### 성능 최적화: 인덱스와 정규화
실무에서 가장 많이 고민하게 되는 부분입니다.
- **정규화(Normalization):** 데이터 중복을 최소화하고 구조를 체계화하는 과정입니다. (1NF, 2NF, 3NF 등)
- **인덱스(Index):** 책의 색인처럼 데이터를 빠르게 찾기 위한 구조입니다. B-Tree 구조가 대표적이죠.
- **실행 계획(Execution Plan):** 작성한 SQL이 내부적으로 어떻게 실행되는지 분석하여 병목을 찾아내는 도구입니다.
---
## 주의
> [!warning] 하지만 데이터 정합성의 경우 RDBMS의 고유한 특징이라고 하기엔 무리가 있다.
왜냐하면 DB라면 데이터 정합성을 지켜야하는게 당연하기 때문이다.
( 얼마나 정합성을 강하게 지켜서 성능에서 손해를 보느냐, 약간 덜 엄격하게 지키고 성능에서 이점을 얻느냐가 차라리 더 중요하다. )
## RDBMS의 본질
> [!note] RDBMS의 본질: "구조적 설계를 통한 중복 제어"
- **정규화(Normalization):** 데이터 간의 관계를 분석해 원자 단위로 쪼개고, 중복을 원천 차단하는 프로세스입니다.
- **무결성 제약 조건:** DB 엔진 차원에서 외래키(FK), 유니크(Unique) 제약 등을 통해 "중복되거나 잘못된 관계가 맺어지는 것"을 물리적으로 막습니다.
- **저장 효율성:** 중복을 최소화하기 때문에 저장 공간을 효율적으로 쓰고, 데이터 수정 시 한 곳만 고치면 되는 구조를 만듭니다.
+72
View File
@@ -0,0 +1,72 @@
---
id: RS-232 vs 이더넷 20260504
created: 2026-05-04 09:58
tags:
aliases:
---
## 💡 생각
결과적으로 RS-232와 이더넷사이에는 약 8,000배의 속도차이가 발생된다고 한다.
설치비용도 이더넷이 훨씬 더 저렴하다고 한다.
이래도 RS-232를 쓴다고?
[[RS-232가 이더넷을 따라잡을 수 없는 이유]]
---
> [!question]
> Q. 왜 rs-232랑 이더넷은 속도의 차이가 나는거야? 어차피 둘다 똑같이 전기적인 신호의 전달인거 아니야?
> A. 정말 좋은 질문입니다! 본질적으로는 둘 다 구리선 안에서 전압의 변화(전기 신호)를 이용하는 것은 맞지만, 그 전기를 **얼마나 정교하고 빠르게 제어하느냐**에서 결정적인 차이가 발생합니다.
---
### 1. 전압의 폭과 물리적 부담 (관성)
전압을 바꾸는 것은 마치 수도꼭지를 틀고 잠그는 것과 비슷합니다.
- **[[RS-232]]:** 전압의 진폭이 큽니다(보통 -15V에서 +15V 사이). 전압을 이만큼 높였다 낮췄다 하려면 시간이 걸립니다. 즉, 신호를 한 번 바꿀 때마다 물리적인 '관성'이 큽니다.
- **이더넷:** 아주 낮은 전압(약 1V~2.5V 내외)을 사용합니다. 전압 폭이 작기 때문에 아주 미세하고 빠르게 전압을 튀길 수 있습니다. 덕분에 1초에 훨씬 많은 신호를 보낼 수 있는 것이죠.
***** 즉, 수도꼭지를 아주 조금만 틀고잠궈도 되는 이더넷이 많이 틀고 많이 잠궈야하는 RS-232보다 물리적인 부담이 훨씬 적다.
### 2. 노이즈를 처리하는 방식 (차동 신호)
멀리, 그리고 빠르게 신호를 보내려면 주변의 전기적 잡음(노이즈)을 이겨내야 합니다.
- **[[RS-232]] (싱글 엔디드):** 선 하나에 전기를 흘리고 그 전압 값만 측정합니다. 주변에서 노이즈가 끼어들면 신호가 쉽게 변조됩니다. 그래서 속도를 높이면 에러가 너무 많이 납니다.
- **이더넷 ([[차동 신호(Differential Signaling)]]):** 선 두 개를 꼬아서 사용합니다. 한쪽 선에 `+`를 보내면 다른 쪽엔 `-`를 보냅니다. 노이즈가 발생해도 두 선에 동시에 영향을 주므로, 두 신호의 '차이'를 계산하면 노이즈만 쏙 제거됩니다. 이 기술 덕분에 노이즈 걱정 없이 엄청난 속도로 신호를 쏠 수 있습니다.
***** 노이즈 발생 걱정 없이 데이터를 송,수신 할 수 있다.
### 3. 신호를 만드는 '언어'의 정교함
전압을 단순히 `높다(1)`, `낮다(0)`로만 구분하는지, 아니면 더 복잡하게 약속하는지의 차이입니다.
- **RS-232:** 단순합니다. 전압이 높으면 0, 낮으면 1(혹은 그 반대) 식으로 아주 기초적인 규칙만 씁니다.
- **이더넷:** 전압의 변화뿐만 아니라 위상(Phase) 등을 조합한 고도의 인코딩 방식을 씁니다. 한 번의 전기 신호 변화에 여러 비트의 데이터를 담는 '압축 기술'이 들어가 있어 같은 전기 신호라도 실어나르는 데이터 양이 훨씬 많습니다.
> [!question]
> Q. 신호를 만드는 '언어'의 정교함 이거는 만약에 rs-232도 고도로 발달한 인코딩 방식을 개발해서 사용했다면 어느정도는 따라갈 수 있는 부분이었을까?
> A. 매우 날카로운 질문입니다! 결론부터 말씀드리면, **인코딩 기술을 도입하면 RS-232도 지금보다는 훨씬 빨라질 수 있습니다.** 하지만 근본적으로 이더넷을 **'완벽히'** 따라잡기는 어렵습니다.
> [!note]
결국 **똑같은 전기**를 쓰더라도, 더 적은 힘으로(저전압), 더 영리하게 노이즈를 방어하면서(차동 신호), 더 정교한 규칙(인코딩)으로 소통하기 때문에 이더넷이 압도적으로 빠른 것입니다.
>
### 왜 RS-232는 차동 신호가 안 될까요?
RS-232는 선 하나($A$)와 접지(Ground, $0V$)를 비교합니다.
- **보낼 때:** $A$선에 $10V$를 보냅니다. (기준은 $0V$니까 차이는 $10V$)
- **노이즈 발생:** $A$선에만 $+5V$ 노이즈가 낍니다. ($15V$가 됨)
- **받을 때:** 받는 쪽은 여전히 $0V$를 기준으로 측정하므로, 데이터가 $15V$로 변질된 채 들어옵니다. 노이즈를 걸러낼 방법이 없습니다.
+57
View File
@@ -0,0 +1,57 @@
---
id: "RS-232 20260504"
created: "2026-05-04 09:37"
tags:
aliases:
---
## 💡 생각
SECS 통신에서 사용하는 그것을 말함.
아직도 RS-232를 쓰는곳이 종종 있음.
---
## 📑 개념
컴퓨터와 주변 장치(모뎀, 마우스, 산업용 장비 등) 간에 데이터를 주고받기 위해 만들어진 **직렬(Serial) 통신 표준**입니다. 1960년대에 처음 등장했음에도 불구하고, 신뢰성이 높고 구조가 간단하여 오늘날까지도 산업 현장에서 널리 사용되고 있습니다.
---
## 📌 주요 특징
- **직렬 통신:** 데이터를 한 번에 1비트씩 순차적으로 전송합니다. 병렬 통신에 비해 배선이 단순하다는 장점이 있습니다.
- **전압 기반 신호:** 논리 상태를 전압의 차이로 구분합니다.
- **논리 0 (Space):** $+3\text{V} \sim +15\text{V}$
- **논리 1 (Mark):** $-3\text{V} \sim -15\text{V}$ (휴지 상태)
- **전송 거리:** 표준상으로는 약 15m(50피트) 정도까지 권장되지만, 통신 속도를 낮추면 더 먼 거리도 가능합니다.
- **커넥터 형태:** 과거에는 25핀(DB-25)이 쓰였으나, 현재는 9핀(DE-9 또는 DB-9) 형태가 가장 흔합니다.
## 통신 방식 (프레임 구조)
RS-232는 **비동기식(Asynchronous)** 통신을 주로 사용합니다. 즉, 송신측과 수신측이 공통된 클록(Clock)을 공유하지 않고, 약속된 속도(Baud Rate)에 맞춰 데이터를 해석합니다.
(Baud Rate: 송신자와 수신자가 미리 **초당 몇 비트를 보낼지** 약속한 것)
1. **Start Bit:** 통신의 시작을 알리는 1비트 (Low 전압).
2. **Data Bits:** 실제 데이터 (보통 7~8비트).
3. **Parity Bit:** 오류 검출을 위한 옵션 비트.
4. **Stop Bit:** 통신의 종료를 알리는 비트 (1~2비트, High 전압).
RS-232는 보통 **전이중(Full-Duplex)** 방식입니다. 즉, 보내는 선(TX)과 받는 선(RX)이 분리되어 있습니다.
- 상대방이 데이터를 다 보낼 때까지 기다렸다가 내가 보내는 방식(Half-Duplex)도 가능하지만,
- 하드웨어적으로 선이 따로 있기 때문에 **상대방이 데이터를 보내는 중에도 내가 보낼 데이터가 있다면 동시에 Start Bit를 던지고 데이터를 보낼 수 있습니다.**
## 요약
- **Start Bit:** 수신기의 타이머를 가동시키는 스위치.
- **데이터 읽기:** 약속된 보레이트의 '절반' 지점마다 전압을 체크해서 0인지 1인지 결정.
- **Stop Bit:** 다음 데이터의 Start Bit를 제대로 인식할 수 있도록 선로를 대기 상태(High)로 복귀시키는 최소한의 여유 시간.
![[Pasted image 20260504100456.png]]
@@ -0,0 +1,49 @@
---
id: "RS-232가 이더넷을 따라잡을 수 없는 이유 20260504"
created: "2026-05-04 10:16"
tags:
aliases:
---
## 💡 생각
가성비를 위해 고안된 RS-232에 이더넷에서 사용하는 고도의 인코딩기술 등을 적용하려면 RS-232의 가장 큰 장점이었던 가성비가 사라지게 된다.
기술적으로도 싱글 엔디드(선 하나로 측정)방식에서 어떻게 할 수 없는 노이즈 현상이 RS-232의 고도화에 가장 큰 걸림돌이기도 하다.
---
### 1. 인코딩으로 얻을 수 있는 이득 (언어의 효율성)
RS-232도 현대적인 인코딩(예: QAM 등)을 사용한다면, 한 번의 전기 변화에 1비트가 아니라 4비트, 8비트를 담을 수 있습니다. 실제로 과거 전화선을 쓰던 **다이얼업 모뎀**이 이런 방식으로 속도를 높여왔습니다.
- 하지만 인코딩을 고도화할수록 **신호가 아주 미세한 차이**를 구분해야 합니다.
- 예를 들어, 전압을 0V/5V 두 개로 나누던 걸 0.1V 단위로 쪼개서 50개의 신호를 만든다고 가정해 보세요.
### 2. 발목을 잡는 '물리적 노이즈' (도로의 상태)
여기서 앞서 공부한 **노이즈** 문제가 다시 등장합니다.
- 고도의 인코딩은 '미세한 전압 차이'를 읽어내는 기술입니다.
- 그런데 RS-232는 노이즈에 취약한 **싱글 엔디드(선 하나로 측정)** 방식이죠.
- 주변에서 노이즈가 조금만 튀어도 0.1V 단위로 쪼개놓은 정교한 신호들이 순식간에 뭉개져 버립니다.
즉, **아무리 고급 언어(인코딩)를 개발해도, 전달 매체(전선)가 너무 시끄러우면(노이즈) 상대방이 알아들을 수가 없는 것**입니다.
### 3. '차동 신호'라는 인프라의 차이
이더넷이 고도의 인코딩을 마음껏 쓸 수 있는 이유는 [[차동 신호(Differential Signaling)]] 덕분에 바닥에 깔린 노이즈를 싹 제거하여 **깨끗한 도화지** 상태를 만들었기 때문입니다.
- **이더넷:** 도화지가 깨끗하니 아주 얇은 펜으로 정밀하게 글씨(인코딩)를 써도 잘 읽힙니다.
- **[[RS-232]]:** 도화지에 이미 연필 자국(노이즈)이 가득해서, 굵은 매직으로 크게 써야만 겨우 읽을 수 있는 상태입니다.
### 4. 하드웨어 설계의 단순성 (경제성)
RS-232는 애초에 "싸고 단순하게 만들자"가 목적이었습니다.
- 복잡한 인코딩을 처리하려면 CPU나 전용 칩셋이 신호를 실시간으로 계산해서 복원해야 합니다.
- RS-232 장치에 그런 비싼 칩을 넣을 바에는, 차라리 그 돈으로 **이더넷 칩**을 하나 다는 게 훨씬 싸고 빠릅니다. 이미 이더넷은 대량 생산으로 가격이 매우 낮아졌으니까요.
@@ -0,0 +1,58 @@
---
id: 게이트웨이(Gateway) 20260428
created: 2026-04-28 14:25
tags:
- network
aliases:
---
## 💡 생각
서로 다른 네트워크간의 통신은 무조건 게이트웨이를 통해 진행된다.
내부를 먼저 확인하고 내부에 그 ip에 해당되는 녀석이 없으면 게이트웨이를 통해 외부로 나아간다.
이 때 가장 먼저 확인하는게 [[라우팅 테이블(Routing Table)]]이다.
---
## 📑 개념
서로 다른 네트워크를 연결해 주는 '출입구' 역할을 하는 장치나 소프트웨어를 말합니다.
컴퓨터 네트워크는 서로 다른 통신 프로토콜(규약)을 사용하거나 구조가 다른 경우가 많은데, 게이트웨이는 이들 사이에서 데이터를 주고받을 수 있도록 **통역사** 역할을 수행합니다.
## ## 1. 게이트웨이의 핵심 역할
네트워크의 경계에 위치하여 다음과 같은 기능을 수행합니다.
- **프로토콜 변환:** 서로 다른 방식의 네트워크가 소통할 수 있도록 신호를 변환합니다.
- **데이터 전달:** 내부 네트워크에서 외부(인터넷)로 나가는 모든 데이터는 반드시 게이트웨이를 통과해야 합니다.
- **보안:** 외부로부터 들어오는 허가되지 않은 접속을 차단하는 벽의 역할을 하기도 합니다.
---
## 2. 실생활 예시: 아파트 현관문
게이트웨이를 가장 쉽게 이해하는 방법은 **아파트의 현관문**에 비유하는 것입니다.
- **내부 네트워크:** 우리 집 안 (가족끼리 자유롭게 대화하고 이동 가능)
- **외부 네트워크:** 집 밖 (복도, 엘리베이터, 거리)
- **게이트웨이:** 현관문 (집 밖으로 나가거나 외부인이 들어올 때 반드시 거쳐야 하는 유일한 통로)
컴퓨터가 인터넷상의 웹사이트에 접속하려고 할 때, 먼저 자신의 네트워크 안에 해당 주소가 있는지 확인합니다. 없다면 일단 기본 게이트웨이(Default Gateway)로 데이터를 보낸 뒤 외부 세계로 나가게 됩니다.
## 3. 기본 게이트웨이 (Default Gateway)
우리가 사용하는 PC나 스마트폰 설정에서 흔히 볼 수 있는 용어입니다.
- 보통 가정에서는 유무선 공유기(루터)의 IP 주소가 기본 게이트웨이 주소가 됩니다.
- 내부망에서 해결할 수 없는 목적지(예: 구글, 네이버 등)로 가는 데이터는 무조건 이 기본 게이트웨이 주소로 전달됩니다.
보통 0.0.0.0에 위치하며 보통은 [[라우터(Router)]]를 가리킨다.
앞서봤듯 통신연결 시도가 발생되면 가장먼저 내부의 같은 네트워크망에 그 ip주소에 해당되는 요소가 있는지 확인하고 없으면 라우팅 테이블을 확인해본다. 거기도 없을 경우 기본 게이트웨이로 가게 되는데 보통 기본 게이트웨이는 라우터로 설정되어 있다.
[[라우터(Router)]]를 통해 연결시도 한 ip로 접근이 되는지 확인해보고 최대한 통신 연결을 시도해보다가 성공,실패하게 된다.
---
@@ -0,0 +1,42 @@
---
id: 관계형 데이터베이스(RDBMS)의 한계 20260420
created: 2026-04-20 10:08
tags:
aliases:
---
## 💡 생각
서버의 수평적확장이 어려움 + 관계가 복잡해지면 조인연산이 느려질 수 있음
---
## 1. 유연하지 못한 스키마 (Rigid Schema)
RDBMS는 데이터를 저장하기 전에 미리 테이블 구조(Schema)를 정의해야 합니다.
- **변경의 어려움:** 서비스 운영 중에 데이터 구조를 변경하려면 `ALTER TABLE`과 같은 작업을 수행해야 하는데, 데이터 양이 많을 경우 시스템 부하가 크고 서비스 중단이 발생할 수 있습니다.
- **비정형 데이터 처리:** SNS 포스트, 로그 파일, 이미지 메타데이터 등 구조가 일정하지 않은 데이터를 담기에는 부적합합니다.
## 2. 수평적 확장(Scaling-out)의 어려움
RDBMS는 기본적으로 단일 서버의 성능을 높이는 **수직적 확장(Scale-up)** 에 최적화되어 있습니다.
- **분산 저정의 복잡성:** 여러 대의 서버에 데이터를 나누어 저장(Sharding)할 수 있지만, 이 경우 데이터 간의 일관성을 유지하고 조인(Join) 연산을 수행하는 것이 매우 까다로워집니다.
- **비용 문제:** 고성능의 단일 서버를 구축하는 비용은 서버를 여러 대 늘리는 비용보다 기하급수적으로 비싸집니다.
## 3. 복잡한 관계와 조인(Join) 성능 저하
데이터 간의 관계가 복잡해질수록 여러 테이블을 연결하는 **조인 연산**이 많아집니다.
- **성능 병목:** 수백만 건 이상의 데이터가 포함된 테이블들을 빈번하게 조인하면 쿼리 실행 속도가 급격히 느려집니다.
- **객체-관계 불일치 (Impedance Mismatch):** 객체지향 프로그래밍 언어의 구조와 RDBMS의 테이블 구조가 서로 달라, 이를 변환하는 과정(ORM 등)에서 복잡성이 증가하고 성능 손실이 발생합니다.
## 4. 대용량 데이터 처리 속도
초당 수만 건 이상의 쓰기 작업이 발생하는 실시간 서비스나 테라바이트(TB) 단위의 데이터를 분석하는 환경에서는 RDBMS의 ACID 트랜잭션 보장 기능이 오히려 독이 될 수 있습니다.
- **잠금(Locking) 현상:** 데이터의 일관성을 위해 특정 행이나 테이블을 잠그는 과정에서 대기 시간이 발생하여 전체적인 처리량이 떨어집니다.
+40
View File
@@ -0,0 +1,40 @@
---
id: "기어비(Gear Ratio) 20260506"
created: "2026-05-06 09:56"
tags:
aliases:
---
## 💡 생각
요약하면 기어비가 클수록 (구동측 기어가 작을수록) 힘이 쌔고 속도가 상대적으로 느리다.
기어비가 작을수록 (구동측 기어가 클수록) 힘이 약하지만 속도가 빠르다.
종동측은 생각하지 않는다. 변속기는 구동측 기어를 변경하는 것이기 때문에
종동측은 타이어쪽에 위치한 기어이기 때문에 이걸 변경하는건 불가능하기 때문이다.
---
## 📑 개념
서로 맞물려 돌아가는 두 개 이상의 기어 사이에서 **회전수와 회전력([[토크]])의 관계**를 나타내는 비율을 말합니다. 기계 장치에서 힘을 키우거나 속도를 조절할 때 가장 기본이 되는 개념입니다.
---
기어비는 보통 **종동 기어(회전력을 받는 쪽)의 잇수**를 **구동 기어(힘을 전달하는 쪽)의 잇수**로 나누어 계산합니다.
(잇수: 톱니바퀴에 있는 이빨 개수를 의미)
$$기어비 = \frac{\text{종동 기어 잇수}}{\text{구동 기어 잇수}}$$
예를 들어, 엔진에 연결된 구동 기어의 이빨이 10개이고, 바퀴에 연결된 종동 기어의 이빨이 30개라면 기어비는 **3:1**이 됩니다. 이는 구동 기어가 3번 회전할 때 종동 기어가 1번 회전한다는 뜻입니다.
(여기서 이빨의 크기는 당연히 같다고 가정한다. 이빨 크기가 서로 다르면 맞물려 돌수가 없으니까)
(힘을 전달하는 쪽이 3번 회전할 때 힘을 받는 쪽이 1번 회전한다.)
힘을 전달하는 쪽(구동 기어)이 힘을 받는 쪽(종동 기어)보다 더 작다는 의미이고 구동측이 3바퀴를 돌아야 종동측이 1바퀴를 돌게 된다.
엔진이 동일한 힘으로 구동측을 돌리고 있다고 가정하면 **구동측 기어가 크기가 작기 때문에 작은 힘**으로도 구동측을 빠르게 돌릴 수 있는 거고 구동측을 빠르게 돌리긴 했지만 구동측 기어의 크기가 작기 때문에 종동측 기어가 많이 돌지는 못한다.
> 참고: [[기어의 크기와 필요한 힘]]의 관계
그래서 구동측 기어가 작으면 엔진으로부터 힘을 받을 때 작은 힘으로도 큰 회전력을 얻을 수 있지만 (힘이 쌔지만) 그 힘으로 종동측을 열심히 돌려도 종동측 기어가 많이 회전하지는 못하기 때문에 속도는 빠르지 않게된다.
#### 요약
|**구분**|**기어비가 높을 때 (큰 기어 연결)**|**기어비가 낮을 때 (작은 기어 연결)**|
|---|---|---|
|**회전 속도**|느려짐|빨라짐|
|**회전력(토크)**|강해짐|약해짐|
|**주요 목적**|큰 힘이 필요할 때 (가속, 등판)|고속 주행이 필요할 때|
@@ -0,0 +1,82 @@
---
id: 기어의 크기와 필요한 힘 20260506
created: 2026-05-06 10:10
tags:
aliases:
---
> [!question]
> Q. 구동측을 지렛대의 원리로 돌린다. 이게 무슨말인지 모르겠어. 그냥 구동측을 돌려야하는데 구동측의 기어가 크면 그만큼 무겁기도 할거니까 그걸 돌리려면 힘이 더 많이든다는거 아니야?
> A. 네, 말씀하신 무게(질량)의 영향도 분명히 있지만, 기계공학에서 말하는 '힘이 더 든다'는 개념은 단순히 무게보다는 **회전 반지름**에 의한 **지레의 원리**와 더 깊은 관련이 있습니다.
## 구동측 기어가 클 때 힘이 더 드는 이유
엔진(또는 당신의 손)이 기어의 중심축을 잡고 돌린다고 가정해 봅시다. 기어의 이빨은 기어의 가장자리에 달려 있죠?
- **기어가 클 때 (지름이 클 때):** 축에서 이빨까지의 거리(반지름)가 깁니다. 이건 엔진 입장에서 **무거운 짐을 긴 막대기 끝에 매달고 들어 올리는 것**과 같습니다. 막대기가 길수록(반지름이 클수록) 엔진이 느끼는 저항감은 훨씬 커집니다.
- **기어가 작을 때 (지름이 작을 때):** 축에서 이빨까지의 거리가 짧습니다. 이건 **무거운 짐을 짧은 막대기 끝에 매달고 들어 올리는 것**과 같습니다. 훨씬 가볍게 느껴지겠죠.
> 기어가 커서 중심축에서 이빨까지의 거리가 길면 엔진이 느끼는 저항감이 훨씬 커진다. 즉 더 많은 힘이 필요하다?
> 지롓대의 원리랑 정반대로 설명한거 아닌가?
> [!question]
> Q. 어.. 이상하지않아? 지렛대의 원리를 이야기할 때 물체와 힘을 주는 부위가 멀수록, 즉 지롓대가 길수록 더 적은 힘이 필요한거 아니였어? 아르키메데스가 아주 긴 지롓대가 나에게 주어진다면 지구도 들어올릴수있다고 했잖아
> A. 맞습니다! 아주 예리한 지적입니다. 아르키메데스의 말처럼 지레가 길수록 힘이 덜 드는 게 물리 법칙의 진리가 맞습니다.
>
> 그런데 제가 앞서 기어에서 설명드린 부분과 반대처럼 느껴지는 이유는, 힘을 어디에 주느냐(힘점)와 어디로 힘이 나가느냐(작용점)의 위치가 기어에서는 우리가 흔히 생각하는 지레와 **반대**이기 때문입니다.
## 1. 아르키메데스의 지레 (힘을 '이득' 보는 구조)
아르키메데스가 말한 상황은 **막대기의 아주 먼 끝부분**을 우리가 누르는 상황입니다.
- **구조:** 받침점으로부터 내가 힘을 주는 곳(핸들/막대기 끝)까지의 거리가 매우 멉니다.
- **결과:** 거리가 멀어질수록 내가 주는 힘은 작아도 되지만, 대신 내가 움직여야 하는 거리는 엄청나게 길어집니다
![[Pasted image 20260506102035.png]]
## 2. 구동 기어의 구조 (힘을 '손해' 보는 구조)
하지만 기어(구동축)를 돌릴 때는 상황이 반대입니다. 엔진이나 우리 다리는 기어의 가장자리가 아니라 '가운데 축'을 돌립니다.
- **구조:** 힘을 주는 곳은 가운데(축)이고, 힘이 전달되어 나가는 곳은 바깥쪽(이빨)입니다.
- **결과:** 중심축에서 이빨까지의 거리(반지름)가 길어질수록, 엔진 입장에서는 '지레의 짧은 쪽을 잡고 긴 쪽 끝에 달린 무거운 물체를 들어 올리려는 상황'이 됩니다.
## 3. 왜 기어가 크면 힘이 더 들까요?
지레를 거꾸로 잡았다고 상상해 보세요.
- 아주 긴 막대기가 있는데, 당신은 **받침점에서 단 1cm 떨어진 곳**을 잡고 반대편 끝에 매달린 100kg짜리 돌을 들어 올려야 합니다.
- 이때 막대기가 길어질수록(기어가 커질수록) 돌을 들어 올리기는 기하급수적으로 힘들어집니다. 지레의 원리를 거꾸로 적용받기 때문이죠.
그래서 **구동 기어**의 지름이 커진다는 건, 엔진 입장에서 **지레의 작용점(이빨)이 점점 더 멀어지는 것**과 같아서 돌리기가 더 힘들어지는 것입니다.
![[Pasted image 20260506102901.png]]
> [!question]
> Q. 그러니까.. 자동차입장에서 구동측 기어가 커져서 거리가 멀어지는게 거리B가 늘어나는게 아니고 거리A가 늘어나는 셈인거라고?
> A. 네, 바로 그겁니다! 아주 정확하게 짚으셨어요.
>
> 보통 우리가 지레를 쓸 때는 **내 팔을 길게 해서(거리 B를 늘려서)** 이득을 보려고 하지만, 자동차 엔진 입장에서는 기어가 커지는 것이 내가 들어 올려야 할 짐까지의 거리(거리 A)가 길어지는 셈입니다.
즉, 기어비가 커진다고 해서 B의 길이가 커지는게 아닌셈이다. A의 길이가 커지는것이다.
B는 그대로인데 A가 길어지면 점점 더 큰 힘을 줘야 같은 물체를 들어올릴 수 있는 것
### 3. 구동 기어에서 변하지 않는 것: 거리 B
거리 B(또는 C)는 받침점(엔진 축의 중심)에서 힘을 주는 곳(엔진이 축을 돌리는 지점)까지의 거리입니다. 엔진 축의 굵기는 기어가 바뀐다고 해서 변하지 않으므로, 이 **거리 B는 항상 짧은 상태로 고정**되어 있습니다.
### 4. 기어가 커질 때 변하는 것: 거리 A
기어가 커진다는 것은 엔진 중심에서 힘이 전달되는 끝부분(이빨)까지의 거리인 **거리 A(또는 D)가 길어지는 것**을 의미합니다.
### 결론: 왜 더 큰 힘이 필요한가?
지레질을 하는데, 내가 잡고 있는 쪽(B)은 아주 짧은데 들어 올려야 할 물체까지의 거리(A)만 계속 길어지는 상황인 거죠.
- **작은 기어:** `받침점-B(나)-A(물체)` → 물체가 가까워서 들기 쉬움 (저단 기어, 힘 좋음)
- **큰 기어:** `받침점-B(나)--------------------A(물체)` → 물체가 너무 멀어져서 들기 매우 힘듦 (고속 기어, 힘 많이 듬)
@@ -0,0 +1,30 @@
---
id: "데이터 정합성(Data Consistency) 20260420"
created: "2026-04-20 08:48"
tags:
aliases:
---
## 💡 생각
저장된 데이터가 얼마나 정확하냐를 생각하면 될 것 같음
정합성이 깨진건 뭔가 데이터가 정확하지 않다고 간단하게 생각하자.
---
## 📑 개념
데이터베이스나 시스템 내의 데이터들이 서로 모순 없이 일관되게 유지되는 상태를 의미합니다. 쉽게 말해, **어디에서 데이터를 조회하더라도 값이 같고 논리적으로 어긋남이 없는 상태**를 말하죠.
단순히 데이터가 정확한지(무결성)를 넘어, 분산된 시스템이나 여러 테이블 간의 관계에서 **데이터가 일치하는가**에 초점을 맞춥니다.
## 정합성이 중요한 이유
### **신뢰도 저하 방지**
사용자가 내 정보 페이지에서는 '주소 A'를 보는데, 주문 결제 페이지에서는 옛날 주소인 '주소 B'가 나온다면 시스템에 대한 신뢰가 깨지게 됩니다.
### **비즈니스 로직 오류 차단**
재고 수량 데이터의 정합성이 맞지 않으면, 실제 물건은 없는데 주문이 접수되는 등의 실무적인 문제가 발생합니다.
## 정합성을 지키는 방법: [[트랜잭션(Transaction)]]
데이터베이스에서는 [[ACID]] 원칙을 통해 [[데이터 정합성(Data Consistency)]]을 보장합니다. 그중 핵심은 [[트랜잭션(Transaction)|트렌젝션]]입니다.
( [[ACID]]원칙을 지키면 정합성이 보장된다. )
---
@@ -0,0 +1,43 @@
---
id: 데이터 조인이 느린 이유 20260420
created: 2026-04-20 10:55
tags:
aliases:
---
## 💡 생각
조인은 무거운 연산이 맞고 인덱스를 잘 걸어야 그나마 좀 빠릿빠릿하게 동작한다.
---
## 📑 개념
관계형 데이터베이스(RDBMS)에서 **조인(Join)** 이 무거운 연산으로 취급되는 이유는 단순히 데이터를 합치는 것을 넘어, 컴퓨터 자원(CPU, Memory, I/O)을 집약적으로 사용하기 때문입니다.
## 📌 상세
### 1. 데이터의 곱집합(Cartesian Product) 기반 탐색
기본적으로 조인은 두 테이블의 행들을 조합하는 과정입니다. 최악의 경우, 한쪽 테이블의 행 개수가 $M$이고 다른 쪽이 $N$이라면 $M \times N$만큼의 연산이 필요할 수 있습니다.
- **비교 횟수:** 적절한 인덱스가 없다면, 시스템은 모든 경우의 수를 하나하나 대조해야 합니다. 데이터가 커질수록 이 비교 횟수는 기하급수적으로 늘어납니다.
### 2. 디스크 I/O 발생
데이터베이스 성능의 가장 큰 병목은 **디스크 읽기**입니다.
- 조인을 수행하기 위해 서로 다른 테이블의 데이터 블록을 메모리(Buffer Pool)로 끌어올려야 합니다.
- 데이터가 너무 커서 메모리 공간이 부족하면, 중간 결과를 다시 디스크에 썼다가 읽는 **Temporary I/O**가 발생하여 속도가 급격히 느려집니다.
> [!question]
> Q. Temporary I/O가 일종의 스왑메모리같은 그런 느낌인거야?
> A. 네, 정확한 비유입니다. **Temporary I/O**는 데이터베이스 입장에서 일종의 **'디스크 기반 스왑(Swap)'** 역할을 한다고 이해하시면 됩니다.
데이터를 처리하려면 메모리에 올려야하는데 처리해야하는 데이터가 너무 커서 db에 할당된 메모리 크기를 초과할 경우 DB는 Temporary I/O 처리를 하게된다.
이게 결국 하드디스크에 데이터를 기록해뒀다가 다시 메모리로 올리는 작업을 의미하기 때문에 속도에 굉장히 큰 악영향을 미치게 된다.
### 3. 인덱스 관리 및 랜덤 액세스
인덱스를 타고 데이터를 찾는 과정에서도 비용이 발생합니다.
- **랜덤 액세스:** 인덱스를 통해 테이블의 실제 데이터 위치를 찾아갈 때, 디스크의 여기저기를 흩어져서 읽어야 하는 '랜덤 액세스'가 발생하며 이는 연속된 데이터를 읽는 것보다 훨씬 느립니다.
---
+37
View File
@@ -0,0 +1,37 @@
---
id: "동기(Synchronous) 20260504"
created: "2026-05-04 09:32"
tags:
aliases:
---
## 💡 생각
영어단어인 싱크의 뜻을 생각하자. 상호간의 싱크를 맞춘다 는 의미로 받아들이면 된다.
그게 통신에서의 수신자,송신자 사이던, 프로그래밍에서의 호출자,함수 사이에서든..
---
## 📑 개념
**송신자와 수신자, 혹은 호출자와 실행자가 같은 시간축 위에서 발을 맞춘다**는 뜻
( 상호간에 싱크를 맞춘다 )
---
## 1. 통신에서의 동기: "우리 같은 박자에 맞추자"
말씀하신 대로 **내가 보낼 때 네가 정확히 들어야 한다**는 의미입니다.
- 이를 위해 두 장치는 똑딱거리는 **클럭(Clock)** 신호를 공유합니다.
- 클럭이 '탁' 올라갈 때 송신자는 데이터를 던지고, 수신자는 그 짧은 순간에 데이터를 낚아챕니다.
- **비유:** 오케스트라 지휘자(클럭)의 손짓에 맞춰 연주자들이 동시에 소리를 내는 것과 같습니다.
---
## 2. 프로그래밍에서의 동기: "너 끝날 때까지 나 아무것도 안 해"
말씀하신 **다른 거 하지 말고 기다려라**라는 해석이 완벽합니다. 전문 용어로는 이를 블로킹(Blocking)이라고도 부릅니다.
- 함수가 호출되면 제어권이 그 함수로 넘어가고, 그 함수가 값을 반환(Return)할 때까지 호출한 쪽의 실행 흐름이 멈춰 있습니다.
- **비유:** 편의점 계산대에서 앞 사람이 계산을 마칠 때까지 뒷사람이 줄을 서서 가만히 대기하는 상황입니다.
+61
View File
@@ -0,0 +1,61 @@
---
id: 라우터(Router) 20260428
created: 2026-04-28 14:32
tags:
- network
aliases:
---
## 💡 생각
랜선으로 연결된 인터넷에서 다음 목적지가 어디인지 알려주는 중간 거점의 역할을 하는 장치
---
## 📑 개념
라우터(Router)는 서로 다른 네트워크를 연결하고, 데이터 패킷이 목적지까지 가는 **최적의 경로(Route)를 찾아주는** 길잡이 역할을 하는 네트워크 장비입니다.
## 1. 라우터의 핵심 기능
라우터의 역할은 크게 두 가지로 나뉩니다.
- **경로 결정 (Routing):** 목적지 IP 주소를 확인하고, 자신의 [[라우팅 테이블(Routing Table)]]을 참조하여 "어떤 길로 가야 가장 빠르고 정확한지" 판단합니다. 내비게이션과 같은 역할입니다.
- **패킷 전달 (Forwarding):** 경로가 결정되면 해당 데이터를 다음 인터페이스(출구)로 실제로 옮겨줍니다.
## 2. 라우터의 작동 원리
라우터는 내부에 라우팅 테이블(Routing Table)이라는 일종의 지도를 가지고 있습니다.
1. **패킷 수신:** 데이터(패킷)가 라우터에 도착합니다.
2. **주소 확인:** 라우터는 패킷에서 목적지 IP 주소를 읽어냅니다.
3. **경로 검색:** 라우팅 테이블에서 이 IP로 가려면 어디로 가야 하는지 찾습니다.
4. **전송:** 가장 적합한 경로로 패킷을 밀어 넣어줍니다.
## 3. 게이트웨이 vs 라우터: 차이점이 뭐야?
질문하신 흐름에서 헷갈릴 수 있는 부분인데, 실무에서는 거의 같은 의미로 쓰이기도 합니다.
- **라우터:** 장비 그 자체를 부르는 이름입니다. (하드웨어적 관점)
- **게이트웨이:** 네트워크의 출입구라는 '역할'을 부르는 이름입니다. (기능적 관점)
> [!info] 우리가 집에서 쓰는 **공유기**는 '라우터' 장비이면서, 동시에 우리 집 네트워크의 '기본 게이트웨이' 역할을 수행하고 있는 것입니다.
## 4. 왜 라우터가 필요한가요?
라우터가 없다면 우리는 옆방에 있는 컴퓨터와는 통신할 수 있어도, 멀리 떨어진 구글이나 네이버 서버와는 소통할 수 없습니다.
- **네트워크 분리:** 너무 많은 기기가 하나의 네트워크에 있으면 트래픽이 몰려 속도가 느려집니다. 라우터는 네트워크를 적절히 쪼개 관리 효율을 높입니다.
- **보안:** 외부 네트워크와 내부 네트워크를 분리하여 1차적인 방어선 역할을 합니다.
> [!question]
> Q. 라우터는 물리적인 장치야? 아니면 소프트웨어야?
> A. 정답부터 말씀드리면, **라우터는 하드웨어(물리적 장치)이기도 하고 소프트웨어이기도 합니다.**
일단은 라우터는 하나의 장치다고 생각하자. (소프트웨어가 탑제된 장치 그 자체)
---
@@ -0,0 +1,54 @@
---
id: "라우팅 테이블(Routing Table) 20260428"
created: "2026-04-28 14:16"
tags:
aliases:
---
## 💡 생각
[[라우팅(Routing)]]이 뭔지 알면 라우팅 테이블도 같이 알 수 있다.
---
## 📑 개념
네트워크에서 라우팅 테이블(Routing Table)은 데이터 패킷이 목적지까지 가장 효율적인 경로로 전달될 수 있도록 경로 정보를 저장해둔 이정표와 같은 데이터베이스입니다.
라우터나 컴퓨터와 같은 네트워크 장비는 패킷을 받으면 이 테이블을 참조하여 다음 어디로 보낼지 결정합니다.
## 1. 라우팅 테이블의 주요 구성 요소
라우팅 테이블은 보통 다음과 같은 정보들을 포함하고 있습니다.
- **목적지(Destination):** 패킷이 최종적으로 도달해야 할 IP 주소나 네트워크 대역입니다.
- **서브넷 마스크(Netmask):** 목적지 주소의 범위를 정의합니다.
- **게이트웨이(Gateway) / 다음 홉(Next Hop):** 목적지에 가기 위해 거쳐야 하는 다음번 장치의 IP 주소입니다.
- **인터페이스(Interface):** 패킷을 내보낼 물리적 또는 논리적 포트(예: eth0, Wi-Fi 등)입니다.
- **메트릭(Metric):** 경로의 우선순위를 정하는 값입니다. 여러 경로가 있을 경우 이 값이 낮을수록 더 좋은 경로로 판단합니다.
---
## 2. 경로 결정 방식 (작동 원리)
패킷이 도착하면 라우터는 다음과 같은 과정을 거칩니다.
1. **가장 구체적인 경로 탐색 (Longest Prefix Match):** 목적지 IP와 가장 많이 일치하는 서브넷 마스크를 가진 경로를 먼저 선택합니다.
2. **디폴트 게이트웨이(Default Gateway):** 테이블에 일치하는 특정 경로가 없을 경우, 모든 외부 트래픽을 처리하는 0.0.0.0 경로(기본 관문)로 보냅니다.
3. **패킷 전달:** 결정된 인터페이스를 통해 패킷을 다음 지점으로 송신합니다.
---
## 3. 라우팅 테이블의 관리 방식
라우팅 테이블에 경로가 추가되는 방식은 크게 두 가지로 나뉩니다.
- **정적 라우팅 (Static Routing):** 관리자가 직접 경로 정보를 입력하는 방식입니다. 보안성이 높고 리소스 소모가 적지만, 네트워크 변화에 자동으로 대응하지 못합니다.
- **동적 라우팅 (Dynamic Routing):** RIP, OSPF, BGP 같은 라우팅 프로토콜을 통해 라우터끼리 서로 정보를 교환하며 테이블을 자동으로 업데이트하는 방식입니다.
---
+23
View File
@@ -0,0 +1,23 @@
---
id: 라우팅(Routing) 20260428
created: 2026-04-28 14:15
tags:
- network
- route
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
네트워크에서 **라우팅**이란 패킷(데이터의 전송 단위)이 출발지에서 목적지까지 갈 수 있는 **최적의 경로를 설정하고, 그 경로를 따라 데이터를 전달하는 과정**을 의미합니다.
## 📌 상세
라우팅은 단순히 길을 찾는 것에 그치지 않고, 다음과 같은 핵심적인 작업을 수행합니다.
- **경로 결정 (Path Determination):** [[라우팅 테이블(Routing Table)]]이라는 지도 정보를 참조하여, 수많은 갈림길 중 어떤 길로 데이터를 보낼지 결정합니다.
- **패킷 포워딩 (Packet Forwarding):** 결정된 경로에 따라 실제로 패킷을 다음 장비(넥스트 홉, Next Hop)로 넘겨주는 물리적인 동작입니다.
---
@@ -0,0 +1,10 @@
| **대상** | **금액 조건** | **결제 라인 (순서)** | **합의 담당자** |
| ----------- | --------- | ----------------------------------- | ------------- |
| **1. 팀원** | 30만원 이하 | 본인 → PM/영업대표 → 팀장 → 사업부장 | 문새별, 김성민 |
| | 30만원 초과 | 본인 → PM/영업대표 → 팀장 → 사업부장 → **대표이사** | 문새별, 김성민, 이훈주 |
| **2. 팀장** | 30만원 이하 | 본인 → 사업부장 | 문새별, 김성민 |
| | 30만원 초과 | 본인 → 사업부장 → **대표이사** | 문새별, 김성민, 이훈주 |
| **3. 사업부장** | 전액 | 본인 → **대표이사** | 문새별, 김성민, 이훈주 |
게시판 경영기획실 및 경영지원실 업무분장 및 결재라인 안내(2026. 01. 01) 참고하시면 됩니다.
- 날짜는 달라졌을수도 있음
@@ -0,0 +1,61 @@
---
id: "변속기(Transmission) 20260506"
created: "2026-05-06 09:54"
tags:
aliases:
---
## 💡 생각
변속기라고 이름붙여놓긴 했지만 사실 따지고보면 기어변환기라고 보는게 더 맞다.
여러개의 기어중에 상황에 맞게 골라서 변경하는거니까
([[기어비(Gear Ratio)]] 를 조절하는 장치)
---
## 📑 개념
엔진에서 발생하는 동력을 주행 상황에 맞게 속도와 회전력([[토크]])으로 조절하여 바퀴에 전달하는 핵심 장치입니다. 엔진은 효율적으로 힘을 낼 수 있는 회전수(RPM) 범위가 정해져 있기 때문에, 변속기가 이를 적절히 변환해 주어야 정지 상태에서 출발하거나 고속으로 주행하는 것이 가능해집니다.
즉, 적절한 [[기어비(Gear Ratio)]]로 구동측 기어를 바꿔주는 역할을 한다.
---
## 1. 변속기의 핵심 역할
- **토크 변환:** 자동차가 처음 출발할 때는 큰 힘이 필요합니다. 이때 변속기는 낮은 기어비를 사용하여 엔진의 회전 속도는 낮추고 바퀴로 가는 회전력을 높입니다.
- **속도 조절:** 고속 주행 시에는 엔진이 너무 과하게 돌지 않도록 기어비를 높여 바퀴를 빠르게 회전시킵니다.
- **후진 및 중립:** 엔진의 회전 방향을 바꾸어 후진하게 하거나, 동력을 차단하여 시동이 꺼지지 않게 유지(중립)합니다.
## 2. 주요 변속기의 종류
### 수동 변속기 (Manual Transmission)
운전자가 클러치 페달을 밟고 직접 기어 레버를 조작하는 방식입니다.
- **장점:** 구조가 단순하고 가벼우며, 동력 전달 효율이 좋아 연비가 우수합니다. 운전의 재미를 느낄 수 있습니다.
- **단점:** 조작이 번거롭고 숙련도가 필요하며, 정체 구간에서 피로도가 높습니다.
### 자동 변속기 (Automatic Transmission)
토크 컨버터를 사용하여 유체의 힘으로 동력을 전달하며, 차량이 스스로 기어를 변속합니다.
- **장점:** 조작이 매우 간편하고 주행이 부드럽습니다.
- **단점:** 수동에 비해 구조가 복잡하고 무거우며, 유체를 거치면서 발생하는 동력 손실이 일부 존재합니다.
### 무단 변속기 (CVT, Continuously Variable Transmission)
고정된 기어 대신 벨트와 풀리(Pulley)를 사용하여 기어비를 연속적으로 변화시키는 방식입니다.
- **장점:** 변속 충격이 전혀 없고, 엔진의 최적 효율 구간을 계속 유지할 수 있어 연비에 유리합니다.
- **단점:** 가속 시 이질감이 느껴질 수 있고, 아주 큰 힘을 견디기에는 내구성에 한계가 있을 수 있습니다.
### 듀얼 클러치 변속기 (DCT, Dual Clutch Transmission)
홀수단과 짝수단 기어를 담당하는 클러치를 각각 두어, 다음 기어를 미리 준비하고 있다가 순식간에 변속하는 방식입니다.
- **장점:** 변속 속도가 매우 빠르고 동력 손실이 거의 없어 고성능 차나 연비 효율을 중시하는 차에 많이 쓰입니다.
- **단점:** 저속 주행 시 약간의 울컥거림이 있을 수 있고 수리비가 상대적으로 비쌉니다.
+32
View File
@@ -0,0 +1,32 @@
---
id: "부가세여부 20260427"
created: "2026-04-27 13:16"
tags:
aliases:
---
---
## 📑 개념
회계 전표를 생성할 때 **부가세 여부**(또는 매입세액 공제 여부)는 해당 지출이 부가가치세 신고 시 **세금을 공제(환급)받을 수 있는 항목인지**를 결정하는 아주 중요한 설정입니다.
단순히 금액에 부가세가 포함되어 있느냐 아니냐를 넘어, 다음과 같은 의미를 갖습니다.
## 📌 상세
일반적으로 '부가세 여부'에 체크를 하거나 '여'로 선택한다는 것은, **해당 거래에서 발생한 부가세를 별도의 부가세대급금(자산) 계정으로 분리하겠다**는 뜻입니다.
- **체크한 경우:** "이 지출은 사업과 관련이 있고, 세법상 공제가 가능한 항목이므로 나중에 세무서에서 부가세를 돌려받겠다."라고 선언하는 것입니다.
- **체크하지 않은 경우(불공제/면세):** 부가세가 포함된 결제더라도 사업과 무관하거나(접대비 등), 면세 항목이라서 공제를 받지 못할 때 사용합니다. 이 경우 부가세는 별도로 분리하지 않고 전액 비용(예: 복리후생비)으로 처리합니다.
### 실무적인 판단 기준 (어떨 때 체크하나요?)
모든 결제에 체크하는 것은 아닙니다. 아래 기준을 참고해 보세요.
- **체크해야 하는 경우 (공제):** 식대(직원용), 사무용품 구입, 업무용 택시비, 소모품비 등 사업 운영에 직접 필요한 지출.
- **체크하지 않는 경우 (불공제):**
- **접대비:** 거래처 선물이나 식사 비용.
- **면세 항목:** 꽃 배달(화환), 농산물 구입, 도서 구입 등(애초에 부가세가 0원임).
- **비영업용 승용차 관련:** 일반 승용차의 기름값이나 수리비(경차나 9인승 이상 제외).
+79
View File
@@ -0,0 +1,79 @@
---
id: 분개(分介) 20260413
created: 2026-04-13 11:08
tags:
aliases:
---
## 💡 생각
돈이 나가고 들어오는것을 나누어서 기록하자. (누락없이 정확하게 기록하기 위해서)
---
## 📑 개념
### 분개(分介): "나누어서 기록하기"
**분개**를 한자로 풀면 **나눌 분(分)**, **낄 개(介)** 자를 씁니다. 즉, 하나의 거래를 **두 부분(왼쪽과 오른쪽)** 으로 나누어 장부에 끼워 넣는다는 뜻이에요.
## 📌 상세
- **쉽게 생각하면?** 거래가 일어났을 때 **원인**과 **결과**를 양쪽에 적어주는 과정입니다.
- 예: 편의점에서 1,000원짜리 물을 샀다면?
- **결과:** 내 손에 물이 생겼다.
- **원인:** 내 주머니에서 1,000원이 나갔다.
- 이렇게 양쪽을 다 기록해야 나중에 돈이 어디로 새 나갔는지 정확히 알 수 있거든요.
### . 차변과 대변: 그냥 "왼쪽"과 "오른쪽"
차변(借邊)과 대변(貸邊)이라는 단어 자체에 너무 의미를 두지 마세요. 그냥 회계 나라의 약속입니다.
- **차변 (왼쪽):** 나에게 **들어온 것** (자산의 증가, 비용의 발생)
- **대변 (오른쪽):** 나에게서 **나간 것** (자산의 감소, 수익의 발생)
---
> [!example]
### 예시 이미지
![[Pasted image 20260413110952.png]]
보여주신 이미지는 아주 전형적인 **분개전표**의 입력 화면입니다. 앞서 말씀드린 차변과 대변이 어떻게 쓰이는지 이 표를 통해 하나씩 짚어드릴게요.
---
### 1. 한 세트의 거래 (행번호 1번과 2번)
이 표에서 가장 중요한 점은 **1번 행과 2번 행이 합쳐져서 하나의 사건**을 나타낸다는 것입니다. 기차표를 사고 40,500원을 쓴 상황을 회계적으로 기록한 것이죠.
### 2. 차변금액 (왼쪽) - 행번호 1번
- **금액:** 40,500원
- **계정과목:** 여비교통비
- **의미:** 내가 돈을 **어디에 썼는지(이유)** 를 나타냅니다.
- **해석:** 출입관리 업무협의를 위해 기차표를 사는 데 40,500원이라는 **비용이 발생**했으므로 왼쪽에 적었습니다.
### 3. 대변금액 (오른쪽) - 행번호 2번
- **금액:** 40,500원
- **계정과목:** 여비교통비 (보통 이 자리에는 현금, 보통예금, 미지급금 등이 들어오지만, 이미지에서는 항목 정리를 위해 같은 과목을 쓰신 것 같네요.)
- **의미:** 돈이 **어디서 나갔는지(출처)** 를 나타냅니다.
- **해석:** 40,500원이라는 **자산이 빠져나갔기** 때문에 오른쪽에 적었습니다.
### 4. 왜 똑같은 금액을 양쪽에 적었나요? (대차평균의 원리)
이미지의 하단을 보시면 **차변 합계**와 **대변 합계**가 둘 다 40,500원으로 똑같아야 합니다.
- 만약 차변은 40,500원인데 대변이 0원이라면? "돈은 썼는데 어디서 났는지 모른다"는 뜻이 되어 오류가 발생합니다.
- 이렇게 양쪽의 무게를 맞춰줌으로써 **장부에 실수가 없음을 증명**하는 것입니다.
+45
View File
@@ -0,0 +1,45 @@
---
id: "분개전표 20260413"
created: "2026-04-13 11:04"
tags:
aliases:
---
## 💡 생각
전표는 돈이 빠져나간 이력만 적혀있으니까 상세하게 알 수가 없음.
전표에 차변과 대변이라는 두가지 구분을 더해 전표를 좀 더 상세하게 적는 방법을 의미
그냥..
5만원이 기차표값으로 빠졌다. (차변)
5만원이 카드결제대금으로 나갈거다. (대변)
둘을 합치면 카드결제대금으로 5만원이 나갈건데 그 5만원은 기차표값이다.
를 나눠서 적어놓은거라고 보면 될 듯
---
## 📑 개념
**[[분개(分介)]]전표**는 앞서 설명해 드린 [[전표]]의 한 종류로, **회계상의 거래를 차변(Debit)과 대변(Credit)으로 나누어 기록하는 서식**을 말합니다.
일반적인 [[전표]]가 단순히 돈이 나가고 들어온 사실에 집중한다면, 분개전표는 그 거래가 회계적으로 어떤 의미를 갖는지 상세하게 분석해서 적는 것이 특징입니다.
## 📌 상세
### 1. 분개전표의 핵심 구성
분개전표에는 반드시 **[[분개(分介)]](Journalizing)** 과정이 포함됩니다.
- **차변 (왼쪽):** 자산의 증가, 부채의 감소, 비용의 발생 등을 기록합니다.
- **대변 (오른쪽):** 자산의 감소, 부채의 증가, 수익의 발생 등을 기록합니다.
- **적요:** 이 거래가 구체적으로 무엇인지 설명을 적습니다. (예: 3월분 사무실 임차료 지급)
### 2. 왜 분개전표를 쓸까?
대부분의 기업은 **복식부기** 원리에 따라 장부를 정리합니다. 단순히 현금이 나갔다(출금전표)는 정보만으로는 부족할 때가 많기 때문입니다.
- **복합 거래 처리:** 현금과 카드를 섞어서 결제하거나, 외상 거래를 기록할 때 유용합니다.
- **오류 방지:** 차변 합계와 대변 합계가 항상 일치해야 하므로(대차평균의 원리), 기록 과정에서의 실수를 바로 잡아낼 수 있습니다.
- **회계 소프트웨어의 기초:** 요즘 사용하는 경리 프로그램(ERP)에 전표를 입력하면, 시스템이 이 분개전표를 바탕으로 재무제표를 자동으로 만들어 줍니다.
---
@@ -0,0 +1,52 @@
---
id: "서브넷 마스크(Subnet Mask) 20260428"
created: "2026-04-28 14:40"
tags:
aliases:
---
## 💡 생각
IP 주소라는 전체 주소 중에서 어디까지가 **동네 이름**이고, 어디서부터가 **집 번호**인지를 알려주는 구분선
---
## 📑 개념
서브넷 마스크(Subnet Mask)는 IP 주소에서 '네트워크 부분'과 '호스트(개별 기기) 부분'을 나누는 기준이 되는 숫자입니다.
## ### 1. 왜 필요한가요?
[[IP]] 주소만 봐서는 이 컴퓨터가 어느 그룹에 속해 있는지 알 수 없습니다. [[서브넷(Subnet)]] 마스크는 이를 논리적으로 쪼개어 다음과 같은 역할을 합니다.
- **그룹화:** 같은 네트워크에 있는 기기들을 하나로 묶습니다.
- **통신 대상 판단:** 데이터를 보낼 때, 대상이 나와 같은 동네(내부망)에 있는지 아니면 [[게이트웨이(Gateway)]]를 통해 밖으로 나가야 하는 다른 동네(외부망)인지 판단하는 기준이 됩니다.
서브넷이 다른 경우 서로 다른 네트워크망에 있는것으로 간주함.
예를들어 서브넷 마스크가 255.255.255.0 인 네트워크에서
IP: 192.168.100.228 와 IP: 192.168.100.229 두 서버는 서로 같은 네트워크망에 있는것이다.
228서버와 229서버는 서로 통신할 때 [[라우팅(Routing)]]이나 [[게이트웨이(Gateway)]]를 거치지않고 다이렉트로 통신이 가능하다.
### 2. 어떻게 작동하나요?
서브넷 마스크는 IP 주소와 똑같이 32비트(4개 덩어리)로 구성되며, 보통 `255``0`을 조합해서 사용합니다.
- **255 (1로 채워진 부분):** "이 자리는 네트워크(동네 이름)를 나타내니 건드리지 마!"라는 뜻입니다.
- **0 (0으로 채워진 부분):** "이 자리는 호스트(개별 기기)를 나타내니 자유롭게 번호를 매겨!"라는 뜻입니다.
> **예시: IP가 `192.168.0.10`이고 서브넷 마스크가 `255.255.255.0`이라면?**
>
> - 앞의 세 덩어리 `192.168.0`은 이 기기가 속한 **네트워크 이름**입니다.
>
> - 마지막 한 덩어리 `10`은 그 네트워크 안에서의 **기기 고유 번호**입니다.
>
### 3. 표기법 (CIDR)
서브넷 마스크는 `255.255.255.0`처럼 길게 쓰기도 하지만, 슬래시(`/`) 뒤에 숫자를 붙여서 짧게 쓰기도 합니다. 이를 **CIDR 표기법**이라고 합니다.
- **`/24`:** 앞에서부터 24비트(3덩어리)가 네트워크 주소라는 뜻입니다. (`255.255.255.0`과 같습니다.)
- **`/16`:** 앞에서부터 16비트(2덩어리)가 네트워크 주소라는 뜻입니다. (`255.255.0.0`과 같습니다.)
---
+46 -3
View File
@@ -5,7 +5,7 @@
> 거대한 네트워크인 [[VPC(Virtual Private Cloud)]]를 더 효율적이고 안전하게 관리하기 위해 **더 작은 단위로 쪼갠 가상 네트워크**
**참고로 VPC도 서브넷도 모두 논리적인 개념, 물리적인 동작은 가용 영역에서 이루어짐**
서브넷(Subnet)은 'Sub-network'의 줄임말로, 하나의 거대한 네트워크를 효율적으로 관리하기 위해 **더 작고 논리적으로 쪼개놓은 부분 네트워크**를 의미합니다.
## 📌 서브넷을 나누는 이유
> [!check]
> - **보안 (Security):** 인터넷에 연결될 공간과 외부로부터 완전히 격리될 공간을 분리하기 위해서입니다.
@@ -29,5 +29,48 @@
| **연결 방식** | **인터넷 게이트웨이(IGW)**와 연결됨 | 인터넷 게이트웨이와 연결되지 않음 |
| **배치 자원** | 로드 밸런서(ALB), 배스천 호스트(Bastion) | **백엔드 서버(.NET)**, 데이터베이스(DB) |
| **비유** | 아파트 정문 안내소 (누구나 방문 가능) | 아파트 내부의 안방 (가족만 접근 가능) |
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
## 1. 왜 서브넷을 만드나요? (서브네팅의 이유)
네트워크를 쪼개지 않고 하나로 크게 쓰면 다음과 같은 문제가 생깁니다.
- **트래픽 과부하:** 모든 기기가 한 공간에 있으면, 불필요한 방송 신호(브로드캐스트)가 너무 많아져 네트워크가 느려집니다.
- **보안 취약:** 한 곳이 뚫리면 전체 네트워크의 모든 기기가 위험에 노출됩니다.
- **관리의 어려움:** 장치가 수만 대라면 어디서 문제가 생겼는지 찾기 매우 힘듭니다.
그래서 서브네팅(Subnetting)을 통해 네트워크를 목적이나 위치에 맞게 작게 분리하여 성능과 보안을 높입니다.
---
## 2. 서브넷은 어떻게 구분하나요? (서브넷 마스크)
IP 주소는 원래 하나처럼 보이지만, 서브넷 개념이 들어가면 두 부분으로 나뉩니다.
1. **네트워크 주소 (Network ID):** 어떤 동네(서브넷)인지 알려주는 주소
2. **호스트 주소 (Host ID):** 그 동네 안의 몇 호(기기)인지 알려주는 주소
이때 어디까지가 동네 주소이고, 어디서부터가 기기 주소인지를 구분해주는 기준점이 바로 서브넷 마스크(Subnet Mask)입니다.
- 예를 들어, `255.255.255.0`이라는 서브넷 마스크는 "앞의 세 덩어리(24비트)는 동네 이름이고, 마지막 한 덩어리만 너의 고유 번호야"라고 지정해주는 역할을 합니다.
## 3. 실생활 예시: 회사 네트워크
한 회사에 100명의 직원이 있을 때, 서브넷을 적용하면 다음과 같이 나눌 수 있습니다.
|**서브넷 이름**|**역할**|**접근 권한**|
|---|---|---|
|**서브넷 A**|개발팀|서버 및 개발 환경 접근 가능|
|**서브넷 B**|인사팀|개인정보 및 급여 시스템 접근 가능|
|**서브넷 C**|방문객용 Wi-Fi|인터넷만 가능, 내부 서버 접근 불가|
이렇게 나누면 개발팀 직원이 실수로 인사팀의 민감한 파일을 들여다보는 일을 물리적으로 차단할 수 있습니다.
## 4. 서브넷 간의 통신
- **같은 서브넷 안:** [[게이트웨이(Gateway)]] 없이 직접 소통합니다. (같은 동네니까요!)
- **서로 다른 서브넷:** 반드시 [[라우터(Router)]](또는 [[게이트웨이(Gateway)]])를 거쳐야 합니다. (다른 동네로 넘어가야 하니까요!)
@@ -0,0 +1,64 @@
---
id: 시리얼 통신(Serial Communication) 20260504
created: 2026-05-04 09:22
tags:
aliases:
- 직렬통신
---
## 💡 생각
구식 통신연결방식이다 생각하면 됨. 옛날꺼니까 단점이 많음
이미 serial로 연결해서 사용중이던 장비를 다뤄야 하는 경우에나 보게되거나 사용하게 됨.
[[RS-232]]는 생각보다 꽤 범용적으로 사용했던거라 아직까지도 남아있는 경우가 있음
---
## 📑 개념
데이터를 하나의 선(Channel)을 통해 **한 번에 1비트씩 순차적으로 전송**하는 방식입니다.
현대의 USB, 이더넷, 그리고 임베디드 시스템에서 널리 쓰이는 RS-232, RS-485 등이 모두 여기에 속합니다.
---
## 1. 핵심 개념: 직렬 vs 병렬
데이터를 보낼 때 여러 개의 선을 사용하는 병렬 통신과 달리, 시리얼 통신은 최소한의 선으로 데이터를 보냅니다.
- **직렬(Serial):** 한 줄로 서서 차례대로 이동 (비용 저렴, 장거리 유리)
- **병렬(Parallel):** 여러 줄로 동시에 이동 (단거리 고속, 케이블 복잡)
## 2. 주요 통신 방식 (동기 vs 비동기)
### 비동기식 통신 (Asynchronous)
클럭(Clock) 신호를 공유하지 않고, 데이터 앞뒤에 **Start Bit**와 **Stop Bit**를 붙여 데이터의 시작과 끝을 구분합니다.
- **대표 사례:** UART (RS-232, RS-485)
- **장점:** 선의 개수가 적음
- **단점:** 통신 속도(Baud Rate)가 양쪽 모두 일치해야 함
### [[동기(Synchronous)]]식 통신
별도의 **클럭 신호선**을 사용하여 송수신 타이밍을 맞춥니다.
- **대표 사례:** SPI, I2C
- **장점:** 데이터 전송 효율이 높고 속도가 빠름
- **단점:** 클럭을 위한 추가 선이 필요함
## 주요 설정 파라미터 (UART 기준)
시리얼 통신을 설정할 때 반드시 맞춰야 하는 4가지 요소입니다.
1. **Baud Rate (보오율):** 초당 전송되는 비트 수 (예: 9600, 115200)
2. **Data Bits:** 한 번에 보낼 데이터의 길이 (보통 8비트)
3. **Parity Bit:** 오류 검출을 위한 비트 (None, Even, Odd)
4. **Stop Bits:** 데이터의 끝을 알리는 비트 (1 또는 2)
---
+81
View File
@@ -0,0 +1,81 @@
---
id: 이더넷(Ethernet) 20260504
created: 2026-05-04 10:35
tags:
aliases:
---
## 💡 생각
근거리 통신(100m 이내)을 위해 만들어진 규격이지만 이 이더넷이 병렬적인 확장을 거치고 이더넷 간의 연결이 아주 커지면서 인터넷이 되었음.
---
## 📑 개념
이더넷은 **LAN(Local Area Network, 근거리 통신망)** 구간에서 데이터 패킷을 어떻게 주고받을지 정의한 통신 규격입니다. IEEE 802.3 규격으로 표준화되어 있으며, 전 세계 유선 네트워크 시장의 대부분을 점유하고 있습니다.
---
## ## 핵심 작동 원리: CSMA/CD
과거 이더넷은 여러 컴퓨터가 하나의 통신 경로를 공유했기 때문에, 데이터 충돌을 방지하기 위해 **CSMA/CD**라는 방식을 사용했습니다.
- **Carrier Sense (회선 감지):** 데이터를 보내기 전 네트워크가 사용 중인지 확인합니다.
- **Multiple Access (다중 접속):** 네트워크가 비어 있으면 누구나 데이터를 보낼 수 있습니다.
- **Collision Detection (충돌 검지):** 데이터를 보내는 중 다른 데이터와 충돌이 발생하면 즉시 전송을 중단하고, 일정 시간 대기 후 다시 시도합니다.
> 최근의 스위치(Switch) 기반 네트워크는 전이중(Full-Duplex) 통신을 지원하여 충돌이 거의 발생하지 않기 때문에 이 방식의 중요성은 예전보다 줄어들었습니다.
## 데이터의 단위: 이더넷 프레임 (Ethernet Frame)
이더넷에서 데이터를 전송할 때는 프레임(Frame)이라는 단위로 쪼개서 보냅니다. 여기에는 단순히 데이터만 들어있는 것이 아니라, 배달을 위한 정보들이 포함됩니다.
- **목적지/출발지 MAC 주소:** 랜카드에 부여된 고유 번호를 통해 어디로 보낼지 결정합니다.
- **타입(Type):** 상위 계층의 프로토콜(IPv4, IPv6 등)이 무엇인지 알려줍니다.
- **데이터(Payload):** 실제 전달하려는 내용입니다.
- **FCS (Frame Check Sequence):** 데이터 전송 중 에러가 발생했는지 검사하는 코드입니다.
## 하드웨어 구성 요소
- **NIC (Network Interface Card):** 흔히 말하는 랜카드입니다.
- **랜 케이블 (UTP):** 카테고리(Cat.5e, Cat.6 등)에 따라 전송 속도가 달라집니다.
- **허브(Hub) 및 스위치(Switch):** 여러 장치를 연결해 데이터를 전달하는 장비입니다. 스위치는 목적지 주소를 읽고 필요한 포트로만 데이터를 보내 효율이 높습니다.
> [!note] 이더넷은 OSI 7계층 중 1계층(물리 계층)과 2계층(데이터 링크 계층)의 역할을 담당하며, 우리가 웹 서핑이나 게임을 할 때 데이터가 안전하게 전달될 수 있는 튼튼한 도로 역할을 수행합니다.
> [!question]
> Q. UTP(랜케이블)가 100미터 정도 유효범위가 된다고 했으니까 원래는 근거리 통신을 생각하고 만든 규격인거야? 이 규격이 병렬적인 확장이 되면서 인터넷이 된거고?
> A. 네, 정확한 통찰입니다. 이더넷은 이름 그대로 처음부터 **LAN(Local Area Network, 근거리 통신망)**, 즉 사무실이나 건물 내부 같은 좁은 범위에서 기기들을 연결하기 위해 설계된 규격이었습니다.
## 1. 이더넷의 태생: '우리끼리' 연결하기
초기 이더넷은 하와이 대학의 무선 네트워크 시스템인 'ALOHAnet'에서 아이디어를 얻어 만들어졌습니다. 당시 목표는 거창한 전 세계 연결이 아니라, **같은 건물 안에 있는 컴퓨터와 프린터를 연결하는 것**이었습니다.
- **100미터의 한계:** UTP 케이블은 전기 신호를 사용하기 때문에 거리가 멀어질수록 신호가 약해지고 감쇄 현상이 일어납니다. 그래서 표준상으로 약 100미터 정도를 유효 거리로 잡았고, 이는 '근거리용'이라는 정체성을 잘 보여줍니다.
-
## 2. 병렬적 확장: 리피터에서 스위치로
이더넷이 100미터의 한계를 넘고 거대해진 비결은 장비를 통한 **계층적/병렬적 확장**에 있습니다.
- **리피터와 허브:** 단순히 신호를 증폭해서 거리를 늘렸습니다. (현재는 거의 사용 안 함)
- **브리지와 스위치:** 네트워크를 구역(세그먼트)별로 나누고, 필요한 곳에만 데이터를 전달해 효율을 높였습니다.
- **광케이블(Fiber Optic):** 건물과 건물, 도시와 도시를 연결할 때는 전기 신호 대신 빛을 사용하는 광케이블 이더넷을 사용합니다. 이 덕분에 전송 거리가 수십 킬로미터까지 늘어났습니다.
## 3. 이더넷이 '[[인터넷(Internetwork)]]'이 된 과정
엄밀히 말하면 **이더넷은 도로**이고, **인터넷은 그 도로 위를 달리는 물류 시스템**입니다.
1. **LAN들의 연결:** 각각의 독립된 이더넷 망들이 생겨났습니다.
2. **라우터(Router)의 등장:** 서로 다른 이더넷 망(LAN)들을 연결해 주는 장비가 보급되었습니다.
3. **TCP/IP의 결합:** 이더넷이라는 물리적 도로 위에 TCP/IP라는 공용 언어를 올리면서, 전 세계의 수많은 이더넷 망들이 하나로 묶여 [[인터넷(Internetwork)]]이 된 것입니다.
@@ -0,0 +1,46 @@
---
id: 인터넷(Internetwork) 20260504
created: 2026-05-04 10:42
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
인터넷은 전 세계의 수많은 컴퓨터 네트워크를 하나로 연결한 **거대한 통신망의 집합체**입니다.
[[이더넷(Ethernet)]]이 '개별적인 도로'라면, 인터넷은 그 도로들이 전 세계적으로 연결되어 거대한 물류 네트워크를 형성한 '지구촌 도로 교통망'과 같습니다.
---
## 1. 인터넷의 기원: 아파넷(ARPANET)
인터넷은 1960년대 미국 국방성의 아파넷(ARPANET)에서 시작되었습니다. 당시에는 핵전쟁과 같은 비상 상황에서도 통신 체계가 마비되지 않도록, 정보를 한곳에 집중시키지 않고 **그물망처럼 분산시키는 기술**을 연구했는데 이것이 오늘날 인터넷의 모태가 되었습니다.
## 2. 인터넷의 작동 원리: TCP/IP 프로토콜
전 세계에는 제조사도 다르고 운영체제도 다른 수많은 컴퓨터가 있습니다. 이들이 서로 소통하기 위해서는 공통된 약속인 프로토콜(Protocol)이 필요한데, 그 표준이 바로 **TCP/IP**입니다.
- **IP (Internet Protocol):** 데이터를 목적지까지 전달하기 위해 각 컴퓨터에 부여된 주소(IP 주소)를 기반으로 길을 찾습니다.
- **TCP (Transmission Control Protocol):** 전송된 데이터가 손실되지 않고 순서대로 정확하게 도착했는지 확인하고 관리합니다.
## 3. 인터넷을 지탱하는 하드웨어: 라우터(Router)
이더넷 망과 또 다른 이더넷 망을 연결해 주는 핵심 장비가 바로 **라우터**입니다.
- 사용자가 데이터를 보내면 라우터는 목적지 IP 주소를 확인합니다.
- 수많은 경로 중 가장 빠르고 효율적인 길을 선택해 데이터를 다음 라우터로 전달합니다(라우팅).
- 이 과정이 반복되면서 데이터는 대륙과 바다를 건너 목적지에 도달합니다.
## 4. 인터넷과 웹(Web)의 차이
많은 분이 인터넷과 웹을 동일하게 생각하시지만, 사실은 층위가 다릅니다.
- **인터넷(Internet):** 데이터를 주고받을 수 있는 물리적인 인프라(도로)입니다.
- **웹(WWW, World Wide Web):** 인터넷이라는 도로 위를 달리는 **서비스(트럭)** 중 하나입니다. 웹 외에도 이메일(SMTP), 파일 전송(FTP), 온라인 게임 등 다양한 서비스가 인터넷 위에서 돌아갑니다.
+40
View File
@@ -0,0 +1,40 @@
---
id: "전표 20260413"
created: "2026-04-13 11:01"
tags:
aliases:
---
## 💡 생각
거래내역을 증빙하는 증빙자료 정도로 생각하면 될듯.. 영수증 이라고 봐도 될거같고
---
## 📑 개념
**전표**는 기업이나 가게에서 거래가 발생했을 때, 그 내용을 증빙하고 기록하기 위해 작성하는 서식입니다. 쉽게 말해 **거래의 핵심 정보를 담은 쪽지**라고 생각하면 됩니다.
## 상세
### 1. 전표에 들어가는 내용
전표에는 나중에 누가 봐도 거래 내용을 알 수 있게 필수적인 정보들이 기록됩니다.
- **거래 날짜**
- **거래 내용** (무엇을 사고팔았는지)
- **거래 금액**
- **거래 상대방**
- **계정과목** (회계상 어떤 항목인지, 예: 복리후생비, 임차료 등)
### 2. 전표의 종류
가장 흔히 쓰이는 3가지 구분법입니다.
- **입금전표**: 현금이 들어왔을 때 작성 (빨간색 테두리인 경우가 많음)
- **출금전표**: 현금이 나갔을 때 작성 (파란색 테두리인 경우가 많음)
- **대체전표**: 현금이 직접 오가지 않는 거래(카드 결제, 계좌 이체, 외상 등)일 때 작성
---
@@ -0,0 +1,72 @@
---
id: 차동 신호(Differential Signaling) 20260504
created: 2026-05-04 10:07
tags:
aliases:
---
## 💡 생각
[[RS-232]]나 이더넷통신의 경우 전압의 차이의 해석이 핵심인데 이 전압에 여러 노이즈가 낄 수 있음.
근데 이 노이즈도 결국 전압의 차이이고 노이즈가 +로 끼든 -로 끼든 상관없이 보정할 수 있는 방법이 바로 차동 신호기법인 것임.
---
## 📑 개념
차동 신호는 **두 개의 신호선**을 사용하여 하나의 정보를 전달하는 전기적 신호 전송 방식입니다. 주로 고속 데이터 통신이나 노이즈가 많은 환경에서 신호의 무결성을 유지하기 위해 사용됩니다.
---
## ### 1. 기본 원리
일반적인 '싱글 엔디드(Single-ended)' 방식이 하나의 신호선과 접지(Ground) 사이의 전압 차를 이용한다면, 차동 신호는 **서로 반대되는 위상을 가진 두 신호**를 이용합니다.
- **V+ (Positive):** 원래의 신호
- **V- (Negative):** 원래 신호와 크기는 같지만 극성이 반대인 신호
수신 측에서는 이 두 신호의 차이($V_{diff} = V_+ - V_-$)를 측정하여 데이터를 복원합니다.
> [!note] 차동 신호(Differential Signaling)의 핵심 원리
> ### 1. 신호를 보낼 때 (송신)
>
> 데이터 `10`을 보내고 싶다고 가정해 보겠습니다. 이더넷은 선 두 개($A$선, $B$선)에 신호를 **반대로** 실어 보냅니다.
>
> - **$A$선 (정위상):** $+10V$
>
> - **$B$선 (역위상):** $-10V$
>
> - 이때 두 선의 차이는 $10 - (-10) = \mathbf{20V}$가 됩니다. 이것이 우리가 보낸 진짜 데이터의 크기입니다.
>
>
> ### 2. 중간에 노이즈가 끼어들 때 (간섭)
>
> 랜선이 지나가는데 옆에 커다란 모터가 돌아서 **$+5V$만큼의 노이즈**가 발생했다고 칩시다. 중요한 건 이 노이즈는 **두 선에 똑같이** 영향을 준다는 점입니다. (선이 꼬여있기 때문이죠.)
>
> - **$A$선:** $10V \text{(데이터)} + 5V \text{(노이즈)} = \mathbf{15V}$
>
> - **$B$선:** $-10V \text{(데이터)} + 5V \text{(노이즈)} = \mathbf{-5V}$
>
>
> ### 3. 신호를 받을 때 (수신 - 뺄셈의 마법)
>
> 데이터를 받는 쪽에서는 $A$선에서 $B$선을 뺍니다.
>
> $$(A \text{선}) - (B \text{선}) = 15V - (-5V) = \mathbf{20V}$$
>
> 보이시나요? **결과값이 처음에 보냈던 차이값인 $20V$와 똑같이 나옵니다.** 노이즈 $+5V$가 양쪽에서 똑같이 더해졌기 때문에, 뺄셈을 하는 순간 서로 상쇄되어 사라져 버린 것입니다.
### 2. 왜 차동 신호를 사용하는가? (주요 장점)
#### 외부 노이즈에 강함 (Common-Mode Rejection)
차동 신호의 가장 큰 장점입니다. 두 신호선이 서로 밀착되어 전송되기 때문에, 외부에서 전기적 노이즈가 유입될 때 두 선 모두에 거의 동일한 양의 노이즈가 더해집니다. 이를 공통 모드 노이즈(Common-Mode Noise)라고 합니다.
- 수신단에서 두 신호를 빼는 과정($V_+ + Noise) - (V_- + Noise)$을 거치면, 동일하게 유입된 노이즈는 서로 상쇄되어 사라지고 순수한 신호만 남게 됩니다.
#### 전자기 방해(EMI) 감소
두 선에 흐르는 전류의 방향이 서로 반대이므로, 각 선에서 발생하는 자기장이 서로를 상쇄합니다. 결과적으로 주변 기기에 끼치는 전자기적 간섭이 줄어듭니다.
#### 낮은 전압으로도 고속 전송 가능
접지(Ground)를 기준으로 삼는 방식보다 신호의 스윙 폭을 작게 가져가도 노이즈에 강하기 때문에, 더 낮은 전압에서 더 빠르게 상태를 전환할 수 있습니다. 이는 전력 소모를 줄이고 속도를 높이는 데 유리합니다.
+43
View File
@@ -0,0 +1,43 @@
---
id: "클러치 20260506"
created: "2026-05-06 10:51"
tags:
aliases:
---
## 💡 생각
클러치는 엔진과 구동측 기어 사이를 연결해주는 중간 연결부품
엔진의 동력을 구동측 기어로 전달해주거나 차단하는 스위치 역할을 한다.
---
## 📑 개념
클러치는 동력을 전달하는 장치와 그 동력을 받는 장치 사이에서 연결을 조절하는 핵심 부품입니다. 주로 자동차의 엔진과 변속기 사이에서 힘을 전달하거나 끊는 역할을 수행합니다.
---
## 1. 클러치의 주요 역할
- **동력의 차단과 연결:** 엔진은 시동이 걸려 있는 동안 계속 회전합니다. 하지만 정차 중이거나 기어를 변속할 때는 바퀴로 가는 동력을 잠시 끊어줘야 하는데, 이때 클러치가 그 연결을 해제합니다.
- **부드러운 출발:** 정지 상태에서 갑자기 엔진의 큰 힘이 바퀴에 전달되면 차가 덜컥거리거나 시동이 꺼질 수 있습니다. 클러치는 이 힘을 서서히 전달하여 차가 부드럽게 움직이게 돕습니다.
- **변속 지원:** 주행 중 속도에 맞춰 기어를 바꿀 때, 엔진과 변속기의 회전 속도를 맞추기 위해 일시적으로 연결을 끊어줍니다.
---
## 2. 작동 원리 (마찰력)
가장 흔한 방식인 **마찰 클러치**를 기준으로 보면, 두 개의 판이 맞닿는 원리를 이용합니다.
1. **연결 상태:** 강한 스프링의 힘으로 클러치 판이 엔진의 플라이휠에 밀착됩니다. 이때 발생하는 **마찰력** 덕분에 엔진의 회전력이 변속기로 전달됩니다.
2. **분리 상태:** 운전자가 클러치 페달을 밟으면, 누르고 있던 스프링의 힘이 해제되면서 판이 떨어집니다. 결과적으로 엔진은 돌고 있지만 변속기로는 힘이 가지 않는 상태가 됩니다.
---
## 3. 전송 방식에 따른 분류
- **수동 변속기 (Manual):** 운전자가 직접 페달을 밟아 클러치를 조작합니다. 섬세한 조절이 필요하며 조작의 재미가 있습니다.
- **자동 변속기 (Automatic):** 클러치 대신 '토크 컨버터'라는 유압 장치를 사용하여 자동으로 동력을 조절합니다.
- **듀얼 클러치 (DCT):** 두 개의 클러치를 사용하여 홀수 단과 짝수 단 기어를 미리 준비해둡니다. 수동의 효율성과 자동의 편리함을 결합해 변속 속도가 매우 빠릅니다.
@@ -0,0 +1,65 @@
---
id: 토크컨버터(Torque Converter) 20260506
created: 2026-05-06 10:50
tags:
aliases:
---
## 💡 생각
즉, 수동 자동차에는 토크컨버터라는 장치가 있을 필요가 없다.
(자동변속기 차량에만 들어가는 부품이다.)
그리고 수동과 자동은 작동원리는 동일하지만 그 원리로 작동하기 위한 과정이 다르다.
수동은 엔진과 기어사이에 직접적인 마찰이 존재하고 자동은 오일(기름)의 움직임으로 간접적인 마찰을 이용한다.
---
## 📑 개념
자동변속기 차량에서 **엔진의 동력을 변속기로 전달하는 유체 [[클러치]]** 장치입니다. 수동변속기 차량이 [[클러치]] 페달을 밟아 물리적으로 동력을 끊고 잇는다면, 자동변속기 차량은 이 토크컨버터 내부의 '기름(오일)'을 이용해 부드럽게 동력을 전달합니다.
---
## 1. 토크컨버터의 기본 원리: 선풍기 비유
토크컨버터의 원리는 마주 보고 있는 두 대의 선풍기를 생각하면 이해하기 쉽습니다.
1. 한쪽 선풍기(엔진 쪽)를 틀면 바람이 나옵니다.
2. 그 바람의 힘으로 맞은편에 꺼져 있는 선풍기(변속기 쪽)의 날개가 돌아가기 시작합니다.
3. 이때 공기 대신 오일(유체)을 사용하여 더 강력하고 효율적으로 힘을 전달하는 것이 토크컨버터입니다.
---
## 2. 내부 핵심 구성 요소
토크컨버터는 크게 세 가지 부품으로 이루어져 있습니다.
- **임펠러 (Pump/Impeller):** 엔진과 연결되어 있으며, 엔진이 회전하면 오일을 밖으로 뿜어내는 역할을 합니다.
- **터빈 (Turbine):** 변속기와 연결되어 있습니다. 임펠러가 뿜어낸 오일의 힘을 받아 회전하며 바퀴에 동력을 전달합니다.
- **스테이터 (Stator):** 임펠러와 터빈 사이에 위치한 작은 날개입니다. 터빈을 돌리고 나오는 오일의 방향을 바꾸어 다시 임펠러 쪽으로 밀어줌으로써 **토크(회전력)를 증폭**시키는 결정적인 역할을 합니다.
---
## 3. 주요 기능
### 1) 토크 증폭 (Torque Multiplication)
정지 상태에서 출발할 때 스테이터가 오일의 흐름을 조절하여 엔진이 만드는 실제 힘보다 더 큰 회전력을 만들어냅니다. 덕분에 무거운 차체가 부드럽게 움직일 수 있습니다.
### 2) 댐퍼 클러치 (Lock-up Clutch)
유체를 통해 힘을 전달하면 아무래도 약간의 미끄러짐(손실)이 발생합니다. 이를 방지하기 위해 고속 주행 시에는 엔진과 변속기를 기계적으로 직접 연결해 버리는데, 이를 락업(Lock-up)이라고 하며 연비를 높여줍니다.
### 3) 부드러운 변속 및 정차
액체로 힘을 전달하기 때문에 기어가 바뀔 때 충격이 적고, 차가 멈춰 있어도 엔진 시동이 꺼지지 않게 해줍니다(엔진은 돌지만 터빈만 멈춰 있는 상태).
> [!note] 토크컨버터는 오일의 순환을 이용해 엔진의 힘을 변속기로 전달하고, 필요할 땐 그 힘을 뻥튀기해 주는 장치라고 이해하시면 됩니다.
> [!question]
> Q. 그럼 자동변속기는 단순히 수동변속기의 변속을 자동으로 해준다는 의미만 있는게 아니네
> 변속기가 작동하는 방식이 아에 다른, 전혀 다른 방식의 기술인거네
> A. 정확합니다! 많은 분이 자동변속기를 단순히 **수동변속기에 로봇 팔을 달아서 대신 변속해 주는 장치** 정도로 생각하시지만, 사실 두 장치는 동력을 전달하고 기어를 바꾸는 **메커니즘 자체가 완전히 다른 별개의 공학 기술**입니다.
@@ -0,0 +1,25 @@
---
id: 트랜잭션(Transaction) 20260420
created: 2026-04-20 08:50
tags:
aliases:
- 트렌젝션
- 트렌잭션
- 트랜젝션
---
## 💡 생각
하나 이상의 쿼리를 묶은 최소 작업 단위
---
## 📑 개념
이터베이스 관리 시스템(DBMS)에서 **하나의 논리적 기능을 수행하기 위한 작업의 단위**입니다. 쉽게 말해, 여러 개의 SQL 문들을 하나의 묶음으로 처리하여 "성공하면 모두 반영, 실패하면 모두 취소"를 보장하는 장치입니다.
## 📌 상세
## 트랜잭션의 4가지 핵심 특성 (ACID)
트랜잭션이 안전하게 수행되기 위해서는 아래 네 가지 성질을 반드시 만족해야 합니다. 이를 [[ACID]]라고 부릅니다.
![[ACID#📌 상세]]
즉 [[데이터 정합성(Data Consistency)]]을 지키기 위해 1개 이상의 쿼리작업을 하나의 트랜잭션으로 묶어서 처리한다.
---
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

+1 -2
View File
@@ -11,6 +11,7 @@ aliases:
## 📑 개념
여기에 이 메모가 다루는 개념을 한 문장으로 정의하세요. (예: 제텔카스텔의 원자성이란 지식의 최소 단위를 의미한다.)
---
## 📌 상세
1. **특징 1**: 내용을 입력하세요.
2. **특징 2**: 내용을 입력하세요.
@@ -23,5 +24,3 @@ aliases:
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
---