간만의 공부.. 내용이 많은데 kui-veil 서버가 잘 처리해낼수 있을까?

This commit is contained in:
2026-04-07 16:04:47 +09:00
parent 4bafee36ee
commit 96e0100d88
31 changed files with 1175 additions and 2 deletions
@@ -0,0 +1,78 @@
---
id: FHS(Filesystem Hierarchy Standard) 20260403
created: 2026-04-03 11:04
tags:
aliases:
---
## 💡 생각
파일구조에 자유도를 억제해서 어느정도 규격화를 해놓은 것,
너무 자유로우면 무슨 파일이 어디에 있는지 확인하기가 매우 어려울텐데
어떤 종류의 파일은 어디에 있어야 하고 이런 규칙을 정의해서
어떤 리눅스를 사용하든 어느정도의 규칙이 존재하기 때문에 원하는 파일을 어느정도 쉽게 찾아갈 수 있게끔 함
---
## 📑 개념
뿌리가 되는 **루트(`/`)** 아래에 모든 것이 가지처럼 뻗어 나가는 **역트리 구조**
리눅스나 유닉스 계열 운영체제를 사용하다 보면 폴더 구조가 왜 이렇게 복잡한지 궁금할 때가 있죠.
**FHS(Filesystem Hierarchy Standard)**는 바로 이런 혼란을 방지하기 위해 파일과 디렉터리의 위치를 정의한 표준 규격입니다.
덕분에 사용자나 소프트웨어 개발자는 어떤 리눅스 배포판을 사용하더라도 특정 파일이 어디에 있을지 예측할 수 있습니다.
## 📌 상세
- **/ (root)**: 모든 파일과 디렉터리의 시작점
: 모든 디렉토리의 시작점입니다. 윈도우의 `C:\`와 비슷하지만, 리눅스에서는 모든 장치(하드디스크, USB 등)가 이 아래의 특정 폴더에 연결(마운트)됩니다.
--- 📂 주요 디렉토리
- **/bin**: 필수적인 사용자 명령 파일 (Binaries)
: 모든 사용자가 쓸 수 있는 기본 명령어들이 들어 있습니다.
- **/sbin**: 시스템 관리용 실행 파일 (System Binaries)
: 시스템 관리자(Root)가 사용하는 명령어들이 모여 있습니다.
- **/etc**: 시스템 설정 파일 (Editable Text Configurations)
: **가장 중요한 폴더 중 하나입니다.** 시스템의 모든 **설정 파일**이 들어 있습니다.
: 사용자 정보(`/etc/passwd`), 네트워크 설정, 설치된 프로그램의 환경 설정 등이 모두 여기에 텍스트 파일로 저장됩니다.
- **/home**: 일반 사용자들의 홈 디렉터리
: 일반 사용자들의 개인 공간, 예를 들어 계정명이 `dihwang`이라면 `/home/dihwang` 폴더가 생기고, 그 안에 바탕화면, 다운로드, 개인 설정 등이 저장됩니다.
: 관리자(root)를 제외한 모든 사용자는 자신의 홈 디렉토리 밖에서는 파일을 맘대로 만들거나 지울 수 없습니다.
- **/root**: 시스템 관리자(root)의 홈 디렉터리
: 시스템 최고 관리자인 **root 사용자의 홈 디렉토리**입니다. 일반 사용자 홈 디렉토리(`/home`)와는 별도로 관리됩니다.
---
--- ⚙️ 시스템 운영을 위한 폴더들
- **/usr**: 사용자 관련 모든 프로그램과 데이터 (User System Resources)
: 사용자가 설치한 프로그램과 데이터들이 모이는 곳입니다. 윈도우의 `C:\Program Files`와 가장 비슷합니다.
: `/usr/bin`: 나중에 설치한 응용 프로그램들의 실행 파일.
: `/usr/lib`: 프로그램 실행에 필요한 공유 라이브러리들.
- **/var**: 가변적인 데이터 저장소 (Variable)
: **내용이 수시로 변하는 데이터**가 저장됩니다.
: `/var/log`: 시스템 로그가 쌓이는 곳입니다. 서버가 왜 죽었는지 확인할 때 필수입니다.
: `/var/www`: 웹 서버(Apache, Nginx)의 소스 파일들이 기본적으로 위치하는 곳입니다.
- **/tmp**: 임시 파일 저장소 (Temporary)
: **임시 파일** 저장소입니다. 부팅 시나 일정 시간이 지나면 자동으로 삭제되는 파일들이 머뭅니다. 누구나 파일을 쓰고 지울 수 있습니다.
- **/dev**: 장치 파일 (Devices)
: 리눅스는 **모든 것을 파일로 관리한다**는 철학이 있습니다. 마우스, 키보드, 하드디스크 같은 물리적인 장치들도 이 폴더 안에 파일 형태로 존재합니다.
- **/mnt**: 수동으로 마운트하는 임시 지점 (Mount)
: 관리자가 수동으로 하드디스크 등을 연결할 때 쓰는 임시 장소.
- **/media**: 외부 장치 자동 마운트 지점 (USB, CD-ROM 등)
: USB나 CD-ROM을 꽂으면 자동으로 연결되는 곳.
- **/opt**: 추가 패키지 소프트웨어 설치 (Optional)
- **/boot**: 부팅 관련 핵심 파일
- **/srv**: 시스템이 제공하는 서비스 데이터 (Service)
: 요즘은 `/var/www` 등을 더 많이 씁니다.
- **/tmp**: 임시 파일 저장소 (Temporary)
- **/lib**: 공유 라이브러리 및 커널 모듈 (Libraries)
---
+38
View File
@@ -0,0 +1,38 @@
---
id: "GNU 20260407"
created: "2026-04-07 14:17"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
**GNU(그누)** 는 리처드 스톨먼이 1983년에 시작한 **자유 소프트웨어 프로젝트**이자, 그 결과로 만들어진 **운영체제**의 이름입니다.
GNU라는 이름은 **GNU is Not Unix**(GNU는 유닉스가 아니다)의 약자로, 자기 자신을 이름 안에 포함해 정의하는 재귀적 약어입니다.
## 1. GNU 프로젝트의 목적
당시에는 소프트웨어 소스 코드를 기업이 독점하고 유료로 판매하는 것이 당연시되었습니다. 리처드 스톨먼은 이에 반대하며 **누구나 소프트웨어를 실행하고, 복제하고, 수정하고, 배포할 수 있는 자유**를 누려야 한다고 주장했습니다. 이를 실현하기 위해 완전히 자유로운 운영체제를 밑바닥부터 만드는 것이 프로젝트의 목표였습니다.
## 2. 주요 구성 요소
운영체제는 단순히 커널(알맹이)만 있다고 작동하지 않습니다. GNU 프로젝트는 운영체제에 필요한 거의 모든 도구를 직접 만들었습니다.
- **GCC (GNU Compiler Collection):** 프로그램을 만드는 컴파일러
- **Glibc:** 시스템 자원을 사용하기 위한 기본 라이브러리
- **Bash:** 사용자의 명령을 입력받는 셸
- **Emacs:** 강력한 기능을 가진 텍스트 에디터
이러한 도구들은 현재 리눅스 환경에서도 표준처럼 사용되고 있습니다.
## 3. GNU와 리눅스의 관계 (중요!)
GNU 프로젝트는 운영체제의 거의 모든 구성 요소를 완성했지만, 정작 시스템의 두뇌 역할을 하는 **커널(Hurd)** 개발이 늦어지고 있었습니다.
이때 1991년, 리누스 토르발스가 **리눅스 커널**을 공개했습니다. GNU 프로젝트가 만든 수많은 소프트웨어와 리눅스 커널이 결합하면서 비로소 완벽하게 작동하는 자유 운영체제가 탄생했습니다. 우리가 흔히 부르는 리눅스는 정확히 말하면 **GNU/리눅스**인 셈입니다.
@@ -0,0 +1,54 @@
---
id: "고차 함수(Higher-Order Function) 20260407"
created: "2026-04-07 15:55"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
함수를 다루는 함수라고 생각하면 쉬워요.
함수가 다음 중 **하나 이상**을 수행한다면 고차 함수라고 부릅니다.
## 고차 함수의 두 가지 조건
### 1. 함수를 인자로 전달받음
다른 함수를 매개변수(Parameter)로 넘겨받아 실행하는 경우입니다. 이때 인자로 전달되는 함수를 보통 **콜백 함수(Callback Function)** 라고 부릅니다.
- **예시:** `Array.prototype.map()`, `filter()`, `forEach()`
``` javascript
const numbers = [1, 2, 3];
// 여기서 map은 고차 함수이고, (n => n * 2)는 콜백 함수입니다.
const doubled = numbers.map(n => n * 2);
```
### 2. 함수를 결과로 반환함
함수 실행의 결과물로 새로운 함수를 만들어 내보내는 경우입니다. 이 방식은 **클로저(Closure)** 나 **커링(Currying)** 기법을 구현할 때 자주 쓰입니다.
- **예시:**
``` javascript
function makeMultiplier(multiplier) {
// 함수 자체를 반환합니다.
return function(value) {
return value * multiplier;
};
}
const triple = makeMultiplier(3);
console.log(triple(10)); // 30
```
---
## 왜 고차 함수를 쓰나요?
고차 함수를 사용하면 코드의 **추상화 수준**을 높일 수 있습니다.
1. **코드의 재사용성:** 복잡한 로직(반복문, 조건문 등)은 고차 함수 내부에 숨기고, 실제 수행할 구체적인 작업만 함수로 갈아 끼울 수 있습니다.
2. **가독성 향상:** `for` 문을 돌리며 배열을 수정하는 대신, `filter`나 `map` 같은 명칭을 사용함으로써 코드가 무엇을 하려는지 의도를 명확히 드러낼 수 있습니다.
3. **함수형 프로그래밍:** 데이터를 직접 변경하지 않고 새로운 데이터를 생성하는 방식(불변성 유지)을 구현하기에 최적입니다.
@@ -0,0 +1,60 @@
---
id: 리눅스에 Nginx를 설치할 때 일어나는 일들 20260403
created: 2026-04-03 11:14
tags:
aliases:
---
### Nginx는 어디에 흩어져 있나요?
Nginx를 설치하면 보통 다음과 같이 각기 다른 폴더에 파일들이 들어갑니다.
| **파일 종류** | **위치 (경로)** | **설명** |
| ------------------ | ----------------- | ------------------------------------------- |
| **실행 파일 (Binary)** | `/usr/sbin/nginx` | 실제 프로그램을 돌리는 "근육"입니다. `/etc`가 아니라 여기에 있습니다. |
| **설정 파일 (Conf)** | `/etc/nginx/` | `nginx.conf` 등이 위치하는 "두뇌"입니다. |
| **기본 웹 콘텐츠** | `/var/www/html` | 웹사이트에 보여줄 HTML 파일들이 있는 "창고"입니다. |
| **로그 파일** | `/var/log/nginx/` | 접속 기록이나 에러가 쌓이는 "일기장"입니다. |
[[FHS(Filesystem Hierarchy Standard)]] 참고
### 왜 `/etc/nginx`가 눈에 잘 띌까요?
우리가 Nginx를 다룰 때 가장 많이 수정하고 접근하는 곳이 `/etc/nginx`이기 때문입니다.
실행 파일인 `/usr/sbin/nginx`는 우리가 직접 건드릴 일이 거의 없습니다. 하지만 "포트 번호를 바꾼다", "도메인을 연결한다" 같은 작업을 할 때는 무조건 `/etc/nginx` 안에 있는 텍스트 설정 파일들을 편집해야 하죠. 그래서 마치 Nginx가 거기 설치된 것처럼 느껴질 수 있습니다.
### 리눅스의 '관습' (설정과 실행의 분리)
리눅스에서 `/etc`**"시스템의 상태를 결정하는 텍스트 데이터"**만 담기로 약속되어 있습니다.
- **이유 1 (백업):** 서버를 옮길 때 `/usr`(프로그램)는 새로 설치하면 되지만, `/etc`(내 설정)는 백업하지 않으면 다 날아갑니다. 그래서 설정만 따로 모아두는 거죠.
- **이유 2 (보안):** 실행 파일이 있는 곳은 읽기 전용으로 보호하고, 설정 파일이 있는 곳만 관리자가 수정할 수 있게 권한을 나누기 위함입니다.
### 💡 확인해보기
궁금하시다면 터미널에 아래 명령어를 입력해 보세요. Nginx 실행 파일이 어디 있는지 바로 알려줄 거예요.
```bash
which nginx
```
아마 `/usr/sbin/nginx`라고 답할 겁니다.
> [!question]
> Q. 아.. /usr 가 사용자 관련 모든 프로그램과 데이터가 있는 폴더고 거기의 system binary sbin 아래에 설치가 된거구나?
> A. 정확합니다! 이해력이 정말 빠르시네요. 리눅스의 설계를 완벽하게 꿰뚫어 보셨습니다.
>
> 방금 말씀하신 내용을 조금 더 구체적으로 연결해 보면 리눅스의 구조가 더 선명해질 거예요.
## 🏗️ /usr 디렉토리의 논리적 구조
리눅스에서 `/usr`는 **User System Resources**의 약자로, 시스템 운영에 필수적인 최소한의 도구(루트 폴더의 `/bin`)를 제외한 **나머지 모든 응용 프로그램**이 거주하는 거대한 도시와 같습니다.
### /usr/bin vs /usr/**s**bin
두개의 `sbin`의 차이는 **누가 실행하는가**에 있습니다.
- **`/usr/bin` (User Binaries):** 일반 사용자가 일상적으로 쓰는 프로그램들입니다. (예: `python`, `git`, `curl` 등)
- **`/usr/sbin` (System Binaries):** 시스템 관리자(Root) 권한이 필요한, 시스템 전체에 영향을 주는 프로그램들입니다.
- **Nginx**는 웹 서버라는 시스템 서비스를 제공하기 때문에 관리자 권한이 필수적이고, 그래서 `sbin`에 위치하게 됩니다.
@@ -0,0 +1,52 @@
---
id: "리눅스와 유닉스의 파일 시스템 20260407"
created: "2026-04-07 13:15"
tags:
aliases:
---
## 💡 생각
아무튼 둘은 거의 비슷하고 리눅스의 경우 기준점을 정해놓고 가능하면 기준을 지키려고 노력하고 유닉스는 기준점이 딱히 없고 버전마다 차이점이 존재할 가능성이 높다.
---
## 📑 개념
유닉스(UNIX)와 리눅스(Linux)의 파일 시스템은 뿌리가 같기 때문에 구조적으로 매우 흡사하지만, 탄생 배경과 발전 과정에 따라 몇 가지 중요한 차이점이 있습니다. 두 시스템 모두 **계층적 트리 구조**를 사용하며 모든 것을 파일로 취급한다는 철학을 공유합니다.
## 📌 상세
## 1. 기본 구조 및 철학 (유사점)
두 시스템 모두 최상위 루트 디렉터리($/$)를 기점으로 하는 단일 트리 구조를 가집니다.
[[FHS(Filesystem Hierarchy Standard)]]라는 표준을 따르기 때문에 주요 디렉터리의 역할은 거의 동일합니다.
- **/bin, /sbin**: 실행 파일
- **/etc**: 설정 파일
- **/home**: 사용자 데이터 (유닉스는 시스템에 따라 `/usr/users` 등을 사용하기도 함)
- **/dev**: 하드웨어 장치 파일
## 2. 주요 차이점
### 디렉터리 배치 표준 (FHS vs 전통적 유닉스)
- **리눅스**: [[FHS(Filesystem Hierarchy Standard)]]라는 엄격한 표준을 만들어 배포판(Ubuntu, CentOS 등) 간의 호환성을 유지합니다. 예를 들어 가변 데이터는 반드시 `/var`에, 사용자 설치 프로그램은 `/usr/local`에 두는 식입니다.
- **유닉스**: 시스템마다 독자적인 전통을 따릅니다. 예를 들어 **Solaris**나 **HP-UX**, **AIX**는 로그 파일이나 시스템 설정 파일의 위치가 리눅스와 미세하게 다를 수 있으며, `/opt` 디렉터리를 더 적극적으로 활용하여 추가 소프트웨어를 관리하는 경향이 있습니다.
### 파일 시스템 종류 (FS Types)
- **리눅스**: 기본적으로 **Ext4**를 가장 많이 사용하며, 최근에는 대용량 데이터와 스냅샷에 유리한 **Btrfs**, **XFS** 등을 채택합니다. 오픈 소스 특성상 새로운 파일 시스템 도입이 매우 빠릅니다.
- **유닉스**: 각 벤더사가 개발한 고유의 고성능 파일 시스템을 사용합니다.
- **Solaris**: ZFS (현존하는 가장 강력한 파일 시스템 중 하나)
- **IBM AIX**: JFS/JFS2
- **HP-UX**: VxFS (Veritas Filesystem)
### 가상 파일 시스템 (VFS) 활용
- **리눅스**: `/proc`이나 `/sys` 같은 **가상 파일 시스템**을 통해 커널 정보와 하드웨어 상태를 실시간으로 노출하는 데 매우 적극적입니다.
- **유닉스**: 유닉스도 `/proc`을 사용하지만, 리눅스만큼 상세한 정보를 제공하지 않거나 시스템 관리를 위해 별도의 전용 명령어를 사용하는 경우가 더 많습니다.
결론적으로, 사용자 입장에서는 디렉터리 구조가 거의 비슷해 보이지만 **내부적인 관리 메커니즘**과 **사용 가능한 파일 시스템의 종류**에서 큰 차이가 발생합니다.
+43
View File
@@ -0,0 +1,43 @@
---
id: 멀티유저(Multi-user) 20260407
created: 2026-04-07 13:21
tags:
- operating-system
- os
aliases:
---
![[윈도우 서버의 멀티 유저#💡 생각]]
참고: [[윈도우 서버의 멀티 유저]]
---
## 📑 개념
**멀티유저(Multi-user) 시스템**은 하나의 컴퓨터 자원(CPU, 메모리, 저장장치 등)을 여러 사용자가 **동시에** 혹은 **시분할 방식**으로 공유하여 사용할 수 있는 환경을 의미합니다. 단순히 여러 명의 계정이 있는 것을 넘어, 시스템이 각 사용자의 작업을 독립적으로 처리하고 관리하는 능력이 핵심입니다.
## 📌 상세
## 1. 멀티유저 시스템의 핵심 메커니즘
시스템이 여러 사용자를 동시에 수용하기 위해 내부적으로는 다음과 같은 기술적 처리가 이루어집니다.
- **자원 공유와 할당:** 운영체제(OS)가 CPU 스케줄링을 통해 각 사용자에게 아주 짧은 시간 동안 자원을 배분합니다. 사용자 입장에서는 마치 혼자 시스템을 사용하는 것처럼 느껴지지만, 실제로는 시스템이 매우 빠르게 사용자들을 전환하며 작업을 처리합니다.
- **사용자 인증 및 권한 관리:** 각 사용자는 고유의 ID와 비밀번호를 통해 시스템에 접속하며, 시스템은 특정 사용자에게 허용된 파일이나 프로그램에만 접근할 수 있도록 보안 정책을 적용합니다.
- **데이터 독립성 및 보안:** 한 사용자의 작업이 다른 사용자의 데이터나 프로그램 실행에 영향을 주지 않도록 **프로세스 격리**와 **메모리 보호** 기능을 수행합니다.
## 2. 주요 특징
|**특징**|**설명**|
|---|---|
|**자원 효율성**|고가의 서버 자원을 한 명의 사용자가 독점하지 않고 여러 명이 나누어 사용함으로써 하드웨어 활용도를 극대화합니다.|
|**데이터 공유**|동일한 데이터베이스나 파일 시스템에 접근하여 협업하거나 정보를 공유하기 용이합니다.|
|**동시성 제어**|여러 사용자가 같은 데이터를 동시에 수정하려 할 때 데이터 무결성을 유지하기 위한 잠금(Locking) 기술이 적용됩니다.|
|**원격 접속**|물리적으로 떨어진 위치에서도 네트워크를 통해 시스템에 접속하여 작업할 수 있습니다.|
## 3. 대표적인 사례
- **서버용 운영체제:** Linux, Unix, Windows Server 등은 설계 단계부터 멀티유저를 상정하고 만들어졌습니다. 수백 명의 개발자가 하나의 서버에 SSH로 접속해 코딩하는 환경이 대표적입니다.
- **메인프레임:** 대규모 금융 기관이나 정부 기관에서 수천 건의 트랜잭션을 동시에 처리하는 대형 시스템입니다.
- **클라우드 컴퓨팅:** AWS, Azure와 같은 환경도 물리적인 서버 자원을 전 세계 수많은 사용자가 멀티테넌트(Multi-tenant) 방식으로 나누어 사용하는 멀티유저의 확장된 개념입니다.
+81
View File
@@ -0,0 +1,81 @@
---
id: 미닉스의 한계 20260407
created: 2026-04-07 13:51
tags:
aliases:
---
## 💡 생각
자유로운 유닉스를 만들기 위해 직접 OS를 만들었다는게 대단하고 그걸 누구나 자유롭게 쓸 수 있도록 공개한게 정말 대단하다.
---
## 📑 개념
리눅스 개발자인 리누스 토르발즈가 리눅스를 개발하게 된 이유.
## 1. 하드웨어 성능 활용의 제한 (386 프로세서)
당시 리누스는 최신 사양이었던 **Intel 80386** 프로세서가 탑재된 PC를 구입했습니다. 이 CPU는 32비트 보호 모드와 강력한 멀티태스킹 기능을 갖추고 있었죠.
- **미닉스의 한계:** 미닉스는 교육용이라는 목적 때문에 사양이 낮은 구형 컴퓨터에서도 돌아가야 했습니다. 그래서 386 CPU의 강력한 성능(세그먼트 하드웨어 등)을 제대로 활용하지 못하고 16비트 기반에 머물러 있었습니다.
( CPU가 한번의 연산으로 처리할 수 있는 데이터의 양의 차이가 어마어마하게 많이 났다. )
```
- **16비트:** 한 번에 $2^{16}$ (65,536)가지의 상태를 표현하고 처리합니다.
- **32비트:** 한 번에 $2^{32}$ (약 42억 9천만)가지의 상태를 처리합니다.
```
( CPU가 데이터를 처리할 때 접근하는 메모리 주소양의 한계의 차이가 어마어마하게 많이 났다. )
```
- **16비트:** 주소를 65,536개까지만 만들 수 있습니다. 용량으로 따지면 겨우 **64KB**입니다. 이 한계를 극복하려고 예전에는 메모리를 쪼개서 관리하는 복잡한 방식을 썼습니다.
- **32비트:** 약 42억 개의 주소를 가질 수 있습니다. 우리가 흔히 아는 **4GB** 메모리까지 인식할 수 있는 단계입니다.
```
- **리누스의 선택:** 그는 자신의 386 컴퓨터 성능을 끝까지 뽑아낼 수 있는 운영체제를 직접 만들고 싶어 했습니다.
( 이런 이유때문에 OS를 개발하기러 했다고..?;; 나였으면 미닉스 말고 유닉스를 샀을텐데)
---
## 2. 라이선스와 폐쇄적인 운영
미닉스는 네덜란드의 앤드류 타넨바움 교수가 운영체제 원리를 가르치기 위해 만든 소프트웨어였습니다.
- **미닉스의 한계:** 미닉스는 오픈 소스가 아니었습니다. 책을 사야 소스코드를 볼 수 있었고, 상업적으로 이용하거나 소스코드를 마음대로 수정해서 배포하는 것이 엄격히 제한되었습니다.
- **리누스의 선택:** 리누스는 ==누구나 자유롭게 기여하고 개선할 수 있는 시스템==을 원했습니다. (이후 리눅스가 GPL 라이선스를 채택하며 폭발적으로 성장한 배경이 됩니다.)
---
## 3. 터미널 에뮬레이터 기능의 부재
실질적으로 리누스가 개발을 시작하게 된 아주 구체적이고 현실적인 이유입니다.
- **미닉스의 한계:** 리누스는 학교 서버에 접속하기 위해 [[터미널 에뮬레이터(Terminal Emulator)]]가 필요했습니다. 하지만 미닉스에 내장된 기능은 그의 마음에 들지 않았고 성능도 부족했습니다.
- **리누스의 선택:** 처음에는 단순히 "성능 좋은 터미널 프로그램"을 만들기 위해 어셈블리어로 하드웨어를 직접 제어하는 코드를 짜기 시작했습니다. 그런데 이 코드가 점점 커지면서 파일 시스템이 붙고 작업 스케줄러가 붙더니 결국 리눅스 [[커널(Kernel)]]이 된 것입니다.
##### 리누스 토르발즈가 이걸 왜 직접 만들었을까?
리누스가 미닉스를 쓸 때 가장 답답했던 건, 학교의 거대한 유닉스 서버에 접속해서 공부하고 싶은데 미닉스에 내장된 터미널 프로그램의 성능이 너무 안 좋았기 때문입니다.
- **성능 문제:** 글자가 화면에 찍히는 속도가 느리거나, 특정 특수 문자가 깨지는 등의 문제가 있었습니다.
- **직접 개발:** 그래서 그는 386 CPU의 기능을 활용해 하드웨어를 직접 제어하며 **"화면에 글자를 아주 빠르게 뿌려주는 기능"** 과 **"키보드 입력을 서버로 바로 보내는 기능"** 을 담은 자신만의 터미널 에뮬레이터를 만들기 시작했습니다.
그 결과물이 점점 살이 붙어 오늘날 전 세계 서버를 지배하는 **리눅스**가 된 것이죠.
---
## 4. 철학적 차이 (마이크로 커널 vs 모놀리식 커널)
이 부분은 타넨바움 교수와 리누스 토르발즈 사이의 유명한 논쟁(TanenbaumTorvalds debate)으로도 잘 알려져 있습니다.
- **미닉스의 설계 (마이크로 커널):** 기능들을 잘게 쪼개어 안정성을 높이는 구조였지만, 당시 기술로는 속도가 느리고 구조가 너무 복잡했습니다.
- **리눅스의 설계 (모놀리식 커널):** 리누스는 성능을 최우선으로 생각하여 모든 핵심 기능을 하나로 묶은 구조를 선택했습니다. 결과적으로 리눅스는 미닉스보다 훨씬 빠르고 강력한 성능을 보여주었습니다.
결국 리누스 토르발즈는 **"내 마음에 쏙 드는, 최신 하드웨어를 제대로 쓰는, 자유로운 유닉스가 없다면 내가 직접 만들겠다"** 는 생각으로 리눅스를 시작한 셈입니다.
당시 리누스가 리눅스를 처음 발표하며 미닉스 뉴스그룹에 올린 메일에서 **단순히 취미일 뿐이고, GNU처럼 크고 전문적인 건 아니다(just a hobby, won't be big and professional like gnu)** 라고 겸손하게 말했던 것은 아주 유명한 일화입니다.
---
+70
View File
@@ -0,0 +1,70 @@
---
id: 순수 함수(Pure Function) 20260407
created: 2026-04-07 15:50
tags:
aliases:
---
## 💡 생각
[[유닉스의 철학과 필터]] 에서의 필터의 개념 중 한가지만 잘하게 + 함께 동작하게 를 지키기 위해서 지켜져야 할 최소한의 조건. 왜냐하면 순수하지 않은 필터는 함께 동작하기가 굉장히 어려워질 수 있고 동작중에 외부의 값을 바꿔버리면서 동작이 제대로 되지 않거나 멈춰버릴수도 있기 때문임.
---
## 📑 개념
외부 상태에 의존하지 않고 오직 입력값에만 반응하며, 외부에 아무런 영향을 주지 않는 '깨끗한' 함수를 의미합니다.
순수 함수가 되기 위해서는 다음 두 가지 조건을 반드시 만족해야 합니다.
## 1. 동일한 입력에는 항상 동일한 출력 (Deterministic)
함수가 실행되는 시점이나 환경에 상관없이, **매개변수(Input)**가 같다면 결과값은 늘 똑같아야 합니다.
- **순수 함수 예시:**
``` javascript
function add(a, b) {
return a + b;
}
```
이 함수는 언제 어디서 실행하든 `add(2, 3)`을 호출하면 무조건 **5**를 반환합니다.
- **비순수 함수 예시:**
``` javascript
let tax = 0.1;
function calculatePrice(price) {
return price + (price * tax); // 외부 변수 tax에 의존
}
```
외부의 `tax` 값이 바뀌면 결과가 달라지므로 순수 함수가 아닙니다. `Math.random()`이나 현재 시간을 가져오는 함수도 실행할 때마다 결과가 달라지기 때문에 비순수 함수에 해당합니다.
## 2. 부수 효과가 없음 (No Side Effects)
함수 내부에서 함수 밖의 상태를 변경하거나, 외부와 상호작용(입출력 등)을 하지 않아야 합니다.
- **피해야 할 부수 효과들:**
- 외부 변수 수정
- 객체나 배열 등 참조형 데이터의 원본 수정
- 콘솔 출력(`console.log`)이나 파일 쓰기
- 네트워크 요청(API 호출)
---
## 순수 함수의 장점
왜 굳이 이렇게 엄격하게 함수를 만들까요? 그 이유는 다음과 같은 이점 때문입니다.
1. **예측 가능성:** 코드가 어떻게 동작할지 머릿속으로 그리기가 훨씬 쉬워집니다.
2. **테스트 용이성:** 외부 환경을 설정(Mocking)할 필요 없이 입력값만 넣으면 되므로 단위 테스트가 매우 간편합니다.
3. **디버깅 효율:** 함수 내부에서 외부를 건드리지 않으니, 버그가 생겼을 때 추적 범위가 확 좁아집니다.
4. **캐싱(Memoization):** 동일 입력에 동일 출력이 보장되므로, 계산이 복잡한 경우 결과를 저장해두고 재사용할 수 있어 성능 최적화에 유리합니다.
> [!note] 프로젝트를 진행할 때 모든 함수를 순수 함수로 만들 수는 없지만(결국 화면 출력이나 데이터 저장이 필요하니까요), 가능한 많은 로직을 순수 함수로 분리하면 전체적인 코드의 안정성이 크게 올라갑니다.
@@ -0,0 +1,27 @@
---
id: "안드로이드 스튜디오 무선디버깅 20260407"
created: "2026-04-07 11:15"
tags:
aliases:
---
### android studio <-> smart phone 무선 디버깅 방법
휴대폰의 설정 > 개발자 옵션으로 들어갑니다.
무선 디버깅 항목을 누릅니다 (스위치만 켜지 말고, 글자를 눌러 상세 페이지로 진입하세요).
화면에 보이는 'IP 주소 및 포트' 정보를 확인합니다.
예: 192.168.0.15:42135 (이 포트는 매번 바뀝니다!)
안드로이드스튜디오에서 터미널을 연다 (alt + f12)
터미널에 아래와같이 입력한다.
#### 1. 혹시 모를 찌꺼기 프로세스 정리
adb kill-server
adb start-server
#### 2. 기기에 표시된 IP와 포트로 직접 연결
adb connect 192.168.0.15:42135
adb 권한 타임아웃 해제
개발자 옵션에 있는 'ADB 권한 타임아웃 해제(Disable adb authorization timeout)' 기능은 보안과 편의성 사이의 균형을 조절하는 옵션입니다.
간단히 설명하자면, "이 PC를 신뢰할까요?"라고 물어봤던 그 인증 유효기간을 무제한으로 늘려주는 기능입니다.
사용자님처럼 안드로이드 스튜디오로 개인 프로젝트나 업무를 하시는 분들은 이 기능을 '켬(Enable)' 상태로 두는 것을 추천합니다.
@@ -0,0 +1,69 @@
---
id: 윈도우 서버의 멀티 유저 20260407
created: 2026-04-07 13:26
tags:
aliases:
---
## 💡 생각
> [!question]
> Q. 윈도우서버의 경우에는 누가 원격접속중일 떄 내가 접속시도를 하면 같은 화면을 둘 이상의 사용자가 동시에 보게되거나 심하면 먼저 접속했던 유저가 접속종료되버리더라고. 윈도우 서버는 이런 멀티유저 환경을 고려하지 않고 설계된거야?
>
> A. 결론부터 말씀드리면, **윈도우 서버(Windows Server) 역시 완벽한 멀티유저를 지원하도록 설계된 운영체제**입니다. 하지만 일반적인 PC용 윈도우(Windows 10/11)와는 라이선스 정책과 기본 설정값이 다르기 때문에 겪으신 현상이 발생하게 됩니다.
왜 나는 윈도우 서버는 멀티 유저를 제대로 지원하지 않는다고 착각한걸까?
---
## 📑 개념
[[멀티유저(Multi-user)]]
![[멀티유저(Multi-user)#📑 개념]]
하지만 나는 종종 mstsc로 윈도우 서버에 접속할 때 누군가의 '어?' 소리를 들은적이 있고 또 내가 작업중에 로그아웃이 되버려서 '어??' 소리를 낸 적이 있다.
이런일이 왜 발생했던걸까?
현재 겪으신 상황은 크게 두 가지 관점에서 이해할 수 있습니다.
## 1. 윈도우의 기본 모드: 관리용 원격 데스크톱 (Admin Mode)
윈도우 서버를 설치하면 기본적으로 **최대 2명**까지 동시 접속을 허용합니다.
- **목적:** 서버 설정 및 유지보수(관리용)입니다.
- **작동 방식:** 만약 2명의 관리자가 이미 접속해 있는 상태에서 3번째 사람이 접속을 시도하면, 시스템은 기존 사용자 중 한 명을 끊어버리거나(Kick), 접속을 거부합니다.
- **화면 공유 현상:** 만약 두 명의 사용자가 **동일한 사용자 계정(예: Administrator)** 으로 접속을 시도하면, 설정에 따라 기존 세션을 뺏어오거나(세션 리커넥트), 같은 화면을 보게 되는 경우가 생깁니다.
## 2. 진정한 멀티유저 환경: 원격 데스크톱 서비스 (RDS)
수십 명의 사용자가 각자의 독립된 바탕화면을 가지고 동시에 작업하려면, 윈도우 서버에서 **RDS(Remote Desktop Services)** 역할을 활성화해야 합니다.
- **독립된 세션:** RDS 환경에서는 각 사용자가 접속할 때마다 운영체제가 **개별적인 가상 데스크톱 환경(Session)** 을 생성해 줍니다. 따라서 옆 사람이 무엇을 하는지 서로 간섭할 수 없습니다.
- **라이선스(CAL):** 윈도우 서버는 기본적으로 관리용 2인 외에 추가 사용자가 접속하려면 **RDS CAL**이라는 별도의 라이선스 비용을 요구합니다. MS의 비즈니스 모델상, 멀티유저 기능을 "유료 옵션"으로 분리해 둔 셈입니다.
**관리 효율성:** 서버 점검을 위해 관리자 두 명 정도만 들어오면 충분하다는 판단입니다.
(돈이 더 큰 이유인거같다.)
## 3. 요약 및 해결책
윈도우 서버가 [[멀티유저(Multi-user)]]를 고려하지 않은 것이 아니라, **비용과 설정의 문제**입니다.
- **먼저 접속한 유저가 튕기는 이유:** 허용된 동시 접속 세션 수(기본 2개)를 초과했거나, 동일한 계정으로 중복 로그인을 시도했기 때문입니다.
- **해결 방법:**
1. **서로 다른 계정 사용:** 사용자마다 개별 계정을 생성하여 접속하면 관리 모드에서도 최대 2명까지는 독립적으로 사용 가능합니다.
2. **RDS 역할 설치:** 3인 이상의 동시 접속이 필요하다면 서버 역할에서 `Remote Desktop Services`를 설치하고 라이선스를 등록해야 합니다.
3. **그룹 정책(gpedit.msc) 수정:** `컴퓨터 구성 -> 관리 템플릿 -> Windows 구성 요소 -> 터미널 서비스 -> 원격 데스크톱 세션 호스트 -> 연결` 항목에서 **원격 데스크톱 서비스 사용자를 하나의 원격 데스크톱 서비스 세션으로 제한** 옵션을 사용 안 함으로 설정하면 동일 계정으로도 여러 세션을 열 수 있습니다.
> [!note] 결국.. 돈이 문제였다
라이센스 문제였을줄이야..
> [!question]
> Q. RDS 역할을 활성화하면 라이센스문제 상관없이 되는거야 아니면 RDs 역할도 설정하고 라이센스비도 내야지 3명이상 동시접속이 가능한거야?
> A. 결론부터 말씀드리면, **RDS 역할 활성화와 라이선스 구매(비용 지불)가 모두 이루어져야** 3명 이상의 동시 접속이 가능합니다.
그냥.. 서버는 리눅스 쓰자. (공짜인데다가 성능도 좋고...)
+54
View File
@@ -0,0 +1,54 @@
---
id: "유닉스(Unix) 20260407"
created: "2026-04-07 13:13"
tags:
aliases:
---
## 💡 생각
HP-UX도 운좋게 사용했는데 앞으로 내가 유닉스를 또 쓸 일이 있을까?
그리고 사실.. 리눅스랑 크게 다른 것 같지도 않았다.
---
## 📑 개념
**유닉스(Unix)** 는 1960년대 후반부터 개발된 **컴퓨터 운영체제(OS)** 로, 현대 컴퓨팅 환경의 뿌리가 되는 아주 중요한 시스템입니다. 오늘날 우리가 사용하는 리눅스, macOS, 안드로이드 등이 모두 유닉스의 철학과 구조를 계승하고 있습니다.
## 📌 상세
## 1. 유닉스의 핵심 특징
유닉스는 처음부터 **다중 사용자**와 **다중 작업**을 염두에 두고 설계되었습니다.
- **멀티태스킹(Multi-tasking):** 여러 개의 프로세스를 동시에 실행할 수 있습니다.
- [[멀티유저(Multi-user)]] 여러 사람이 동시에 시스템에 접속해서 사용할 수 있습니다.
- **계층적 파일 시스템:** 모든 데이터를 디렉터리(폴더) 구조로 관리하며, 심지어 하드웨어 장치까지도 파일로 취급합니다.
[[리눅스와 유닉스의 파일 시스템]]
- **높은 이식성:** 대부분 C언어로 작성되어 있어, 다양한 하드웨어 환경에 맞춰 수정하고 설치하기가 매우 쉽습니다.
## 2. 유닉스의 시스템 구조
유닉스는 크게 세 가지 계층으로 나뉩니다.
- [[커널(Kernel)]]: 운영체제의 심장부입니다. 하드웨어를 제어하고 메모리, 프로세스, 파일 시스템 등을 관리하는 가장 핵심적인 역할을 합니다.
- **셸(Shell):** 사용자와 커널 사이의 다리 역할을 합니다. 사용자가 명령어를 입력하면 이를 해석해서 커널에 전달합니다. (예: bash, zsh 등)
- **유틸리티/애플리케이션:** 사용자가 실제로 사용하는 프로그램들입니다. 컴파일러, 편집기, 네트워크 도구 등이 여기에 해당합니다.
## 3. [[유닉스 철학 (The Unix Philosophy)]]
![[유닉스 철학 (The Unix Philosophy)#개념]]
---
## 4. 유닉스의 계보와 영향
유닉스는 시간이 지나면서 여러 갈래로 발전했습니다.
- **BSD 계열:** 캘리포니아 대학교 버클리 캠퍼스에서 발전시킨 버전으로, 현재의 **macOS**와 **iOS**의 기반이 되었습니다.
- **System V 계열:** 상용 유닉스의 표준이 된 버전입니다.
- **리눅스(Linux):** 유닉스는 아니지만 유닉스의 작동 방식을 본떠 만든 **유닉스 계열(Unix-like)** 운영체제입니다. 현재 서버와 모바일 시장의 절대 강자죠.
+40
View File
@@ -0,0 +1,40 @@
---
id: 커널(Kernel) 20260407
created: 2026-04-07 13:40
tags:
- operating-system
- os
- hardware
- computer
- computer-science
aliases:
---
## 💡 생각
실제 하드웨어 자원을 관리하고 사용자의 요청에 하드웨어를 조작해주는 관리자.
사용자 <-> 하드웨어 사이의 인터페이스는 모두 커널이 해준다고 보면 됨.
---
## 📑 개념
운영체제(OS)의 **커널(Kernel)** 은 한마디로 **컴퓨터의 심장이자 모든 자원을 관리하는 관리자**라고 할 수 있습니다. 사용자가 실행하는 프로그램과 컴퓨터의 하드웨어 사이에서 다리 역할을 수행하는 아주 핵심적인 소프트웨어 계층입니다.
## 1. 커널의 핵심 기능
커널은 사용자가 직접 하드웨어를 제어하지 못하게 막으면서, 대신 안전하고 효율적으로 자원을 배분합니다.
- **프로세스 관리**: 여러 개의 프로그램이 동시에 실행될 수 있도록 CPU 사용 시간을 나누고 관리합니다.
- **메모리 관리**: 각 프로그램이 어느 정도의 메모리를 사용할지 결정하고, 서로의 영역을 침범하지 못하게 보호합니다.
- **파일 시스템 관리**: 하드디스크나 SSD에 데이터를 저장하고 읽어오는 방식을 제어합니다.
- **장치 드라이버 제어**: 모니터, 키보드, 마우스 등 각종 하드웨어와 통신하여 명령을 전달합니다.
- **시스템 호출(System Call) 제공**: 응용 프로그램이 하드웨어 자원을 쓰고 싶을 때 커널에 요청할 수 있는 통로를 제공합니다.
---
### 우리 주변의 커널 예시
- **Linux 커널**: 안드로이드 스마트폰, 서버용 OS, 임베디드 기기 등에서 널리 쓰이는 대표적인 **단일형 커널**입니다.
- **NT 커널**: 우리가 쓰는 **Windows**의 핵심입니다. **혼합형 커널** 구조를 가지고 있습니다.
- **XNU 커널**: macOS와 iOS의 뿌리가 되는 커널로, 마이크로 커널(Mach)과 단일형 커널(BSD)의 특징을 결합한 형태입니다.
@@ -0,0 +1,51 @@
---
id: 터미널 에뮬레이터(Terminal Emulator) 20260407
created: 2026-04-07 14:01
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
**터미널 에뮬레이터(Terminal Emulator)** 는 쉽게 말해 **"진짜 물리적인 터미널 기계가 없어도, 소프트웨어로 그 기계가 있는 것처럼 흉내 내어 컴퓨터와 대화하게 해주는 프로그램"** 입니다.
이 개념을 이해하려면 과거의 하드웨어 터미널이 무엇이었는지 먼저 아는 것이 중요합니다.
---
## 1. 과거의 "진짜" 터미널 (Hard Terminal)
아주 옛날에는 컴퓨터(메인프레임)가 집채만 했습니다. 그래서 사용자는 컴퓨터 본체에 직접 앉을 수 없었고, **화면과 키보드만 달린 입력 장치**를 멀리 떨어진 곳에 두고 통신선으로 연결해서 썼습니다. 이걸 **터미널(단말기)** 이라고 불렀습니다.
- **본체:** 계산과 처리를 담당 (거대한 서버)
- **터미널:** 명령어를 입력하고 결과를 화면에 뿌려주는 역할만 수행 (두뇌가 없음)
![[Pasted image 20260407140335.png]]
## 2. 터미널 "에뮬레이터"의 등장
세월이 흘러 개인용 PC(데스크톱)가 보급되면서, 더 이상 화면만 달린 커다란 터미널 기계가 필요 없게 되었습니다. 하지만 서버나 운영체제는 여전히 과거 터미널 방식의 **텍스트 기반 명령어**로 대화하도록 설계되어 있었죠.
그래서 PC 안에서 **"마치 내가 예전의 그 터미널 기계인 것처럼 속여서"** 운영체제와 대화할 수 있게 해주는 소프트웨어를 만들었는데, 이것이 바로 터미널 에뮬레이터입니다.
- **하는 일:** 사용자가 키보드로 친 글자를 운영체제에 전달하고, 운영체제가 보낸 텍스트 결과를 화면에 예쁘게 그려줍니다.
- **대표적인 예:** * **Windows:** 명령 프롬프트(CMD), PowerShell, Windows Terminal
- **macOS:** Terminal.app, iTerm2
- **Linux:** GNOME Terminal, xterm
> [!warning] 셸(Shell)과의 차이점 (중요!)
많은 분이 헷갈려 하시는데, 둘은 역할이 다릅니다.
- **터미널 에뮬레이터:** 글자가 보여지는 **창(Window)** 그 자체입니다. (껍데기)
- **셸(Shell):** 그 창 안에서 내 명령을 해석해서 실행해주는 **프로그램(통역사)** 입니다. (예: bash, zsh)
즉 터미널 에뮬레이터는 putty와 매우 비슷하다고 보면 됨.
@@ -0,0 +1,36 @@
---
id: "함수형 프로그래밍(Functional Programming) 20260407"
created: "2026-04-07 15:46"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
**함수형 프로그래밍(Functional Programming)** 은 유닉스 철학의 필터 개념을 프로그래밍 언어의 문법과 구조로 가장 완벽하게 구현해낸 방법론이라고 할 수 있습니다.
[[유닉스 철학 (The Unix Philosophy)]]이 운영체제 수준에서 **프로그램**을 쪼개고 연결한다면, 함수형 프로그래밍은 코드 수준에서 **함수**를 쪼개고 연결합니다.
## 함수형 프로그래밍이 필터가 되는 방식
함수형 프로그래밍의 핵심 개념들은 유닉스 필터의 특성과 일대일로 대응됩니다.
### 1. [[순수 함수(Pure Function)]] = 완벽한 필터
순수 함수는 외부 상태를 변경하지 않고 오직 입력값에 의해서만 결과값을 반환합니다. 이는 유닉스 필터가 입력(stdin)을 받아 출력(stdout)을 내보내는 과정에서 시스템의 다른 곳을 건드리지 않는 것과 같습니다.
- **입력 → [ 함수(Filter) ] → 출력**
### 2. [[고차 함수(Higher-Order Function)]]와 합성 (Composition)
유닉스에서 파이프(`|`)를 사용해 여러 명령어를 잇는 것처럼, 함수형 프로그래밍에서는 **함수 합성**을 통해 작은 필터들을 조립합니다.
- 유닉스: `cat file.txt | grep "error" | wc -l`
- 함수형: `count(filter(read("file.txt"), "error"))` 혹은 파이프 연산자를 사용하여 더 직관적으로 표현할 수 있습니다.
### 3. 불변성 (Immutability)
필터가 원본 데이터를 훼손하지 않고 새로운 데이터를 만들어 내보내듯, 함수형 프로그래밍에서도 기존 데이터를 수정하는 대신 항상 새로운 데이터를 반환합니다. 덕분에 데이터 흐름을 추적하기가 매우 명확해집니다.