<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>red_truth.log</title>
        <link>https://velog.io/</link>
        <description>컴퓨터공학/경영 전공생 :)</description>
        <lastBuildDate>Sun, 31 Mar 2024 08:51:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. red_truth.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/red_truth" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Unix] 시간 & 파일 관련 기초 함수 정리]]></title>
            <link>https://velog.io/@red_truth/Unix-%EC%8B%9C%EA%B0%84-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EC%B4%88-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@red_truth/Unix-%EC%8B%9C%EA%B0%84-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EC%B4%88-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 31 Mar 2024 08:51:31 GMT</pubDate>
            <description><![CDATA[<h1 id=""></h1>
<ol>
<li><p><strong>int stat(const char pathname, struct stat statbuf);</strong></p>
<p> ⇒ 파일명으로 파일 정보를 검색하는 함수이다.</p>
<ul>
<li><p>‘pathname’: 정보를 추출할 파일 명</p>
</li>
<li><p>‘statbuf’: 검색한 파일 정보를 저장할 구조체 주소</p>
<p>→ 파일에 대한 읽기 권한이 주어져야 함</p>
<p>→ 성공시 0 반환 &amp; stat 구조체에 파일 정보 저장, 실패시 -1 리턴</p>
</li>
<li><p>stat 구조체</p>
<p>```c
struct stat {
  dev_t         st_dev;               //파일이 위치한 장치의 ID를 나타낸다.
  ino_t         st_ino;               //파일의 inode(파일 시스템의 고유한 식별자)이다.
  mode_t        st_mode;              //파일의 모드와 권한을 나타낸다.
  nlink_t       st_nlink;             //파일에 대한 하드 링크 수를 나타낸다.
  uid_t         st_uid;               //파일 소유자의 사용자 ID이다.
  gid_t         stgid;                //파일 소유그룹의 그룹 ID읻
  dev_t         st_rdev;              //파일이 시스템 외부 장치로연결된 경우, 해당 장치의 ID를 나타낸다
  off_t         st_size;              //파일의 크기(바이트)를 나타낸다.
  blksize_t     st_blksize;           //파일 시스템에서 사용하는 블록의 크기를 나타낸다.
  blkcnt_t      st_blocks;            //파일이 사용하는 파일 시스템의 블록 갯수를 나타낸다.
  time_t        st_atime;             //파일에 마지막으로 엑세스한 시간을 나타낸다.
  time_t        st_mtime;             //파일의 마지막 수정 시간을 나타낸다.
  time_t        st_ctime;             //파일의 마지막 변경 시간 (메타데이터 포함)을 나타낸다.
};</p>
</li>
</ul>
</li>
</ol>
<ul>
<li>inode란? 파일 시스템에서 파일을 식별하는데 사용되는 고유한 식별자이다. 파일의 메타데이터 및 데이터 블록 위치를 가리키는 포인터 역할을 한다.</li>
<li>예시</li>
</ul>
<p>  ```c
     #include &lt;stdio.h&gt;
     #include &lt;sys/stat.h&gt;</p>
<pre><code> int main() {
  const char *pathname = &quot;example.txt&quot;;
  struct stat statbuf;

  if (stat(pathname, &amp;statbuf) == 0) {
      printf(&quot;File size: %lld bytes\n&quot;, (long long)statbuf.st_size);
      printf(&quot;File mode: %o\n&quot;, statbuf.st_mode);
      // 여기에 다른 파일 속성에 대한 출력 추가 가능
  } else {
      perror(&quot;stat&quot;);
      return 1;
  }

  return 0;</code></pre><p>  }<br>2. <strong>struct tm *localtime(const time_t *timer);</strong></p>
<pre><code>⇒ 컴퓨터의 시간 (1970년 1월 1일 00시 00분 부터 지금까지의 초단위 시간 정수값)을 인간의 시간으로 변환시켜주는 함수

→ 성공시 tm 구조체 포인터가 반환된다; 실패시 NULL이 반한된다.

```c
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
int main() {
  time_t t;              //time_t는 ISO C라이브러리에서 시스템 시간을 저장하도록 정의 된 자료형이다. ㅅ
                                                 //표준함수인 time()의 리턴값
  t = time(NULL);
  printf(&quot;%lld&quot;, t);
  return 0;
}

결과 값: 1711870258
```

- tm 구조체

```c
struct tm {
   int tm_sec;         /* seconds,  range 0 to 59          */
   int tm_min;         /* minutes, range 0 to 59           */
   int tm_hour;        /* hours, range 0 to 23             */
   int tm_mday;        /* day of the month, range 1 to 31  */
   int tm_mon;         /* month, range 0 to 11             */
   int tm_year;        /* The number of years since 1900   */
   int tm_wday;        /* day of the week, range 0 to 6    */
   int tm_yday;        /* day in the year, range 0 to 365  */
   int tm_isdst;       /* daylight saving time             */    
};
```

- 예시 1

```c
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;

int main() {
    time_t rawtime;
    struct tm *info;
    time (&amp;rawtime);
    info = localtime (&amp;rawtime); 
    printf(&quot;Current local time and date: %s&quot;, asctime(info)); 
    //asctime은 struct tm 구조체를 인수로 받아 해당 시간을 문자열로 변환한 후 반환한다.

    return 0;
}

결과 값: Current local time and date: Sun Mar 31 16:38:18 2024
```
- 예시 2
~~~c
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;fcntl.h&gt;

int main (int argc, char *argv[]) {
struct stat statbuf;

if(argc != 3) {
  printf(&quot;Error with arguments\n&quot;);
  exit(EXIT_FAILURE);
}

if (stat(argv[1], &amp;statbuf) == -1){
  perror(&quot;Error: stat&quot;);
  exit(EXIT_FAILURE);
} else {
  printf(&quot;st_dev = %ld\n&quot;, (long)statbuf.st_dev);
  printf(&quot;st_mode = %o\n&quot;, statbuf.st_mode);
  printf(&quot;st_uid = %d\n&quot;, statbuf.st_uid);
  printf(&quot;st_gid = %d\n&quot;, statbuf.st_gid);
  printf(&quot;st_size = %lld\n&quot;, (long long)statbuf.st_size);
  printf(&quot;st_mtime = %ld\n&quot;, (long)statbuf.st_mtime);
  //modified time
  struct tm *tm = localtime(&amp;statbuf.st_mtime);
  printf(&quot;modified time = %d/%d/%d %02d:%02d:%02d\n&quot;, tm-&gt;tm_year+1900, tm-&gt;tm_mon+1, tm-&gt;tm_mday, tm-&gt;tm_hour, tm-&gt;tm_min, tm-&gt;tm_sec);
}

return 0;
}
~~~</code></pre><ol start="3">
<li><p><strong>int utime(const char *filename, const struct utimbuf *times);</strong></p>
<p> ⇒ Unix및 Unix 계열 시스템에서 파일의 마지막 접근 및 수정 시간을 변경하는데 사용된다.</p>
<ul>
<li><p>‘const char *filename’: 변경할 파일의 경로를 나타내는 문자열 포인터</p>
</li>
<li><p>‘const struct utimbuf *times’: 파일의 새로운 접근 및 수정 시간을 지정하는 구조체 포인터</p>
<p>→ 성공시 0, 실패시 -1 반환</p>
</li>
<li><p>utimbuf 구조체</p>
<pre><code class="language-c">struct utimbuf {
  time_t actime;  // 파일의 마지막 접근 시간을 나타내는 Unix 시간(epoch time)
  time_t modtime; // 파일의 마지막 수정 시간을 나타내는 Unix 시간(epoch time)
};</code></pre>
</li>
</ul>
</li>
</ol>
<ul>
<li><p>예시</p>
<pre><code class="language-c">  #include &lt;stdio.h&gt;
  #include &lt;utime.h&gt;
  #include &lt;sys/stat.h&gt;

  int main() {
  const char *filename = &quot;example.txt&quot;;
  struct utimbuf times;

  // 새로운 액세스 및 수정 시간 설정 (예: 2024년 3월 31일 12시 30분 45초)
  times.actime = 1748793045; // 액세스 시간
  times.modtime = 1748793045; // 수정 시간

  // utime 함수 호출하여 파일의 액세스 및 수정 시간 설정
  if (utime(filename, &amp;times) == 0) {
      printf(&quot;Access and modification times for file %s changed successfully.\n&quot;, filename);
  } else {
      perror(&quot;utime&quot;);
      return 1;
  }

  return 0;
}</code></pre>
</li>
</ul>
<ol start="4">
<li><p><strong>int chmod (const char *pathname, mode_t mode);</strong></p>
<p> ⇒ 파일의 모드를 변경하는 데 사용된다.</p>
<ul>
<li><p>‘const char *pathname’: 모드를 변경할 파일의 경로를 나타내는 문자열 포인터</p>
</li>
<li><p>‘mode_t mode’: 파일에 적용할 새로운 모드를 나타내는 값을 가진 변수입니다.</p>
</li>
<li><p>파일 모드 표현 (읽기, 쓰기, 실행 순)</p>
<ul>
<li>Onwer 권한: S_IRUSR, S_IWUSR, S_IXUSR</li>
<li>Group 권한: S_IRGPR, S_IWGRP, S_IXGRP</li>
<li>Other 권한: S_IROTH, S_IWOTH, S_IXOTH</li>
</ul>
<p>→ 성공 0, 실패 -1 반환</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;sys/stat.h&gt;

int main(){
  const char *pathname = &quot;example.txt&quot;;
  mode_t new_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH; //744

  if (chmod(pathname, new_mode) == 0) {
      printf(&quot;File mode changed successfully.\n&quot;);
  } else {
          perror(&quot;Error w/ chmod&quot;);
          return 1;
  }

  return 0;
}


</code></pre>
</li>
</ul>
</li>
</ol>
<ol start="5">
<li><p><strong>int chown (const char* pathname, uid_t owner, gid_t group);</strong></p>
<p> ⇒ 파일의 소유자와 그룹을 변경하는데 사용된다.</p>
<ul>
<li><p>‘const char *pathname’: 모드를 변경할 파일의 경로를 나타내는 문자열 포인터</p>
</li>
<li><p>‘uid_t owner’: 파일의 새로운 Owner의 ID를 나타내는 값</p>
</li>
<li><p>‘gid_t group’: 파일의 새로운 Group의 ID를 나타내는 값</p>
<p>→ 성공 0, 실패 -1 반환
```c
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
int main(){
const char *pathname = &quot;example.txt&quot;
uid_t new_owner = 1000; // 예를 들어, 새로운 소유자의 사용자 ID가 1000이라 가정하면
gid_t new_group = 100; // 예를 들어, 새로운 그룹의 그룹 ID가 100이라 가정하면</p>
<p>if (chown(pathname, new_owner, new_group) == 0) {
printf(&quot;File owner and groupd changed successfully.\n&quot;);
} else {</p>
<pre><code>  perror(&quot;chown&quot;);
  return 1;</code></pre><p>}</p>
<p>return 0;
}</p>
</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Posix I/O system calls 함수 정리]]></title>
            <link>https://velog.io/@red_truth/Posix-IO-system-calls-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@red_truth/Posix-IO-system-calls-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 30 Mar 2024 15:22:28 GMT</pubDate>
            <description><![CDATA[<p><strong>→ Posix: Portable Operating System Interface</strong></p>
<ul>
<li>UNIX 운영 체제에서 파일 시스템 및 프로세스 제어를 위한 API를 정의하는 표준이다.</li>
</ul>
<p><strong>→ File Descriptor</strong></p>
<p>UNIX 및 UNIX-like 운영 체제에서 파일을 식별하고 접근하기 위한 정수형 식별자이다. file descriptor은 프로세스가 파일을 열거나 생성할 때 커널이 할당해 주는 고유한 식별자이다. 일반적으로는 정수값으로 표현되며 0 (표준입력), 1 (표준출력), 2(표준 에러)와 같은 의미를 가진다. 하지만 일반적으로 0,1,2 index는 std-in/std-out/error와 관련된 fd로 미리 할당되고 보통 open()을 호출하면 3을 리턴받게 된다.</p>
<p><strong>→ Open file description</strong></p>
<p>unix 및 unix-like 운영 체제에서 파일에 대한 메타데이터 및 상태정보를 저장하는 내부 데이터 구조이다. 파일이 열릴 때 커널에 의해 생성 되며, 해당 파일에 대한 정보를 추적하고 관리하는데 사용된다. Open file description은 다음과 같은 정보가 포함될 수 있다. Open file description은 파일을 참조하는 file descritor과 연결되어 있으며, 이를 통해 파일을 식별하고 조작할 수 있다. Open file description은 프로세스의 file table에 저장되어 있으며, 해당 파일을 다루는 데 필요한 정보들을 제공한다.</p>
<ol>
<li>파일 상태: 파일의 현재 상태를 나타내는 플래그. ex) 읽기 전용, 쓰기전용</li>
<li>파일 오프셋: 파일 내 현재 읽거나 쓰고 있는 위치를 나타낸다. 오프셋 값을 조작하며 파일을 읽고 쓸 위치를 제어할 수 있다.</li>
<li>파일 권한 및 모드: 파일의 소유자, 그룹, 권한등을 나타낸다.</li>
<li>기타 메타데이터</li>
</ol>
<p>→ <strong>File Table:</strong> 커널이 관리하는 모든 열려진 테이블이다</p>
<p>Posix I/O 시스템 호출의 주요 목적</p>
<ol>
<li>파일 조작: 열고 닫으며, 읽고 쓰는 등의 파일 조장을 수행한다.</li>
<li>파일 디스크립터 관리: 파일 디스크립터를 생성하고, 복제하며, 닫는 등의 관리를 수행한다.</li>
<li>파일 오프셋 조작: 파일 내의 오프셋을 이동하여 파일을 읽거나 쓸 위치를 지정한다.</li>
<li>파일 상태 확인: 파일의 상태를 확인하여 파일의 크기, 권한 등의 정보를 가져온다.</li>
</ol>
<p>1.int open (const char *pathname, int flags, [mode_tmode]);</p>
<p>   ⇒ open() 함수는 file과 file descriptor간의 연결을 설정한다. 이 함수는 파일을 참조하는 open file description과 그 description을 참조하는 file descriptor을 생성하다. file descriptor은 다른 I/O 함수에서 해당 파일을 참조하는 데 사용된다.</p>
<ul>
<li><p>‘pathname’: 열고자 하는 파일의 경로를 나타내는 문자열이다.</p>
<ul>
<li>‘flags’: 파일을 열 때의 동작을 지정하는 플래그이다. ex) 읽기</li>
<li>‘mode’: 파일의 권한을 지정하는 값이다. 사용자, 그룹 및, 기타 사용자의 권한을 지정한다. 파일을 처음 생성할 때만 사용된다.</li>
</ul>
<p>|fcntl.h에 정의된 flag 상수 값|
| --- | --- |
| O_RDONLY | 읽기 전용으로 열기 |
| O_WRONLY | 쓰기 전용으로 열기 |
| O_RDWR | 읽기 및 쓰기 모드로 열기 |
| O_CREAT | 파일이 존재하지 않으면 새로운 파일 생성하기 |
| O_TRUNC | 파일을 열 때 기존 파일의 내용을 지우기 |</p>
<pre><code class="language-c">#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;

int main() {
   // 파일 경로
   const char *file_path = &quot;example.txt&quot;;

   // 파일을 읽기 전용으로 열기
   int fd = open(file_path, O_RDONLY);

   if (fd == -1) {
       perror(&quot;open&quot;);
       exit(EXIT_FAILURE);
   }

   // 파일 디스크립터 출력
   printf(&quot;File descriptor: %d\n&quot;, fd);

   // 파일을 읽기 전용으로 열었으므로 파일 내용을 읽을 수 있음
   // 이후에는 파일을 다루는 작업을 수행할 수 있음

   // 파일을 닫음
   if (close(fd) == -1) { //파일을 닫는 동시에 에러가 나는지 확인한다.
       perror(&quot;close&quot;);
       exit(EXIT_FAILURE);
   }

   return 0;
}
</code></pre>
</li>
</ul>
<ol start="2">
<li><p>int close(int fd);</p>
<p> ⇒ 파일을 닫을 때 사용된다. 반환 값이 -1이면 파일을 닫는 도중 에러가 발생했음을 의미한다.</p>
</li>
<li><p>ssize_t read(int fd, void *buf, size_t count);</p>
<p> ⇒ file descriptor가 가리키는 파일에서 데이터를 읽어오는 역할을 한다.</p>
<ul>
<li><p>‘fd’: 읽을 파일을 가리키는 file descriptor이다.</p>
</li>
<li><p>‘buf’: 읽은 데이터를 저장할 버퍼의 포인터이다. 읽은 데이터는 이 버퍼에 저장된다.</p>
</li>
<li><p>‘count’: 읽을 데이터의 바이트 수 이다. 버퍼의 크기나 읽을 데이터의 크기를 지정한다.</p>
<p>→ 만약 에러가 발생하면 -1을 반환하고, 더 이상 읽을 데이터가 없으면 0을 반환한다.</p>
<p>→ 만약 데이터 읽기에 성공하였으면, 읽어온 데이터의 크기를 반환한다.</p>
<p>→ tip. ssize_t는 signed size type의 약자, 부호있는 정수형의 크기를 나타냄.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;

#define BUFFER_SIZE 1024

int main() {
  int fd;
  ssize_t bytes_read;
  char buffer[BUFFER_SIZE];

  // 파일 열기
  fd = open(&quot;example.txt&quot;, O_RDONLY);
  if (fd == -1) {
      perror(&quot;open&quot;);
      exit(EXIT_FAILURE);
  }

  // 파일에서 데이터 읽기
  bytes_read = read(fd, buffer, BUFFER_SIZE);
  if (bytes_read == -1) {
      perror(&quot;read&quot;);
      exit(EXIT_FAILURE);
  }

  // 읽은 데이터 출력
  printf(&quot;Read %zd bytes: %s\n&quot;, bytes_read, buffer);

  // 파일 닫기
  if (close(fd) == -1) {
      perror(&quot;close&quot;);
      exit(EXIT_FAILURE);
  }

  return 0;
}
</code></pre>
</li>
</ul>
</li>
<li><p>ssize_t write(int fd, const void * but, size_t count);</p>
<pre><code class="language-c"> #include &lt;stdio.h&gt;
 #include &lt;stdlib.h&gt;
 #include &lt;fcntl.h&gt;
 #include &lt;unistd.h&gt;
 #include &lt;string.h&gt;

 int main() {
     int fd;
     ssize_t bytes_written;
     const char *data = &quot;Hello, world!\n&quot;;

     // 파일 열기
     fd = open(&quot;output.txt&quot;, O_WRONLY | O_CREAT | O_TRUNC, 0644);
     if (fd == -1) {
         perror(&quot;open&quot;);
         exit(EXIT_FAILURE);
     }

     // 파일에 데이터 쓰기
     bytes_written = write(fd, data, strlen(data));
     if (bytes_written == -1) {
         perror(&quot;write&quot;);
         exit(EXIT_FAILURE);
     }

     // 파일 닫기
     if (close(fd) == -1) {
         perror(&quot;close&quot;);
         exit(EXIT_FAILURE);
     }

     return 0;
 }
</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[1. 운영체제 (Operating System)  Introduction]]></title>
            <link>https://velog.io/@red_truth/1.-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Operating-System-Introduction</link>
            <guid>https://velog.io/@red_truth/1.-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Operating-System-Introduction</guid>
            <pubDate>Sun, 24 Mar 2024 15:25:47 GMT</pubDate>
            <description><![CDATA[<h2 id="운영체제란-무엇인가">운영체제란 무엇인가?</h2>
<h3 id="운영체제는-도대체-무엇이고-어떤-녀석들로-구성되어-있는지-알아보자">운영체제는 도대체 무엇이고 어떤 녀석들로 구성되어 있는지 알아보자.</h3>
<hr>
<p><strong>운영체제</strong>:컴퓨터의 정부. 하드웨어와 어플리케이션 사이에서 하드웨어 자원을 적절히 분배하고 어플리케이션의 질서를 관장하는 역할을 한다.</p>
<ul>
<li>운영체제는 완벽히 정확한 정의가 없는데, 이는 경계가 불분명하기 때문이다.</li>
<li>Abraham Silberschatz외 2명의 저자가 작성한 Operating System Concepts (공룡책)에 따르면 커널 + 미드웨어 프로그램 + 시스템 프로그램을 묶어서 운영체제로 정의한다.</li>
<li><strong>커널</strong>은 OS의 중심이다. 커널은 컴퓨터 시스템의 모든것을 완전히 제어하며 컴퓨터가 돌아가는 한 항상 실행중인 프로그램이다..</li>
<li><strong>미들웨어 프로그램</strong>은 응용 프로그램 개발자에게 추가 서비스를 제공하는 일련의 소프트웨어 프레임 워크이다. (예. 데이터베이스, 멀티미디어, 그래픽)</li>
<li><strong>시스템 프로그램</strong>은 운영체제와 관련이 있지만 반드시 커널의 일부일 필요는 없는 프로그램을 일컫는다.</li>
<li><blockquote>
<p>이중 가장 중요한 녀석은 커널이다. 때때로 커널 그 자체가 OS로 정의될 때도 있다.</p>
</blockquote>
</li>
</ul>
<h3 id="컴퓨터-시스템-구성요소">컴퓨터 시스템 구성요소</h3>
<hr>
<p><img src="https://velog.velcdn.com/images/red_truth/post/611224f9-449a-4a83-b7e9-1c7215baee02/image.png" alt=""></p>
<ul>
<li>하드웨어: 기본적인 컴퓨팅 자원을 제공한다 (예: CPU, 메모리 입출력 장치)</li>
<li>운영체제: 다양한 응용 프로그램과 사용자들 사이에서 하드웨어 사용을 제어하고 조정한다.</li>
<li>응용 프로그램: 시스템 자원을 사용하여 사용자의 컴퓨팅 문제를 해결하는 방법을 정의한다. (예: 워드 프로세서, 웹 브라우저, 컴파일러, 데이터베이스 시스템, 비디오 게임)</li>
<li>사용자: 사람, 기계 다른 컴퓨터 등이 될 수 있다.</li>
<li><blockquote>
<p>위 그림에서 볼 수 있듯이, 운영체제는 하드웨어와 어플리케이션 프로그램 사이에서 자원을 배분하고 차례를 조정하는 역할 등을 담당한다.</p>
</blockquote>
</li>
</ul>
<h3 id="운영체제의-목적">운영체제의 목적</h3>
<hr>
<p>그렇다면 운영체제의 목적은 과연 무엇이라고 할 수 있을까?</p>
<ol>
<li>운영체제는 환경을 제공한다</li>
</ol>
<ul>
<li>운영체제가 정부와 같은 역할을 하는 이유이다. OS는 혼자서는 쓸모가 없다.</li>
<li>그러나, 운영체제는 사용자가 무언가를 쉽게 해낼 수 있는 환경을 제공한다</li>
</ul>
<ol>
<li>운영체제는 시스템 리소스를 제어한다.</li>
</ol>
<ul>
<li>우주에 모든 것이 그러하듯이 컴퓨터가 돌아갈 때도 자원이 필요하다. 운영체제는 그러한 자원을 유저나 프로그램에게 적절히 배분하며 컴퓨터가 효율적으로 동작하게 만든다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA (Java Persistence API) 기초]]></title>
            <link>https://velog.io/@red_truth/JPA-Java-Persistence-API-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@red_truth/JPA-Java-Persistence-API-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Mon, 05 Feb 2024 12:54:40 GMT</pubDate>
            <description><![CDATA[<h2 id="정의">정의</h2>
<hr>
<p>JAP는 자바 진영에서 객체관계 매핑 (ORM)을 위한 API (인터페이스 모음)이자 Java Persistence Framework (자바 영속성 프레임워크)중 하나로, 데이터베이스와 자바 객체 간의 매핑을 편리하게 처리하는 기술이다. JAP를 사용하면 개발자는 SQL 쿼리를 직접 작성하지 않고도 객체 지향적인 방식으로 데이터를 다룰 수 있다. JAP는 대표적으로 Hibernate, EclipseLink와 같은 구현체를 사용하여 데이터베이스와 상호 작용한다. MyBatis또한 자바 영속성 프레임워크에 속하지만, JPA는 조금 더 객체지향적인 반면, MyBatis는 SQL에 대한 유연성이 더 높다.</p>
<ul>
<li><p><strong>이때 매핑(mapping)이란?</strong></p>
  <div>→ 이때 매핑이란 두 가지 다른 도메인 또는 시스템 간에 대응되는 부분을 지정하거나 연결하는 과정을 나타낸다.</div><br />

  <div>→ 자바 진영에서 ORM기술 중 하나인 JPA는 데이터베이스의 테이블과 자바 언어의 객체간의 매핑을 제공한다. 이는 객체와 관계형 데이터베이스 간에 존재하는 구조적 차이를 극복하기 위한 기술이다.</div><br />

  <div>→ 간단하게 설명하면, 매핑은 객체의 필드(속성)을 데이터베이스의 테이블 열 (Column)에, 객체 간의 연관성을 데이터베이스의 관계로 매칭시키는 작업을 말한다. 이를 통해 객체 지향적인 코드를 유지하면서도 데이터베이스에 데이터를 저장하고 조회할 수 있다.</div><br />

  <div>ex) JPA에서는 엔티티 클래스의 필드를 데이터베이스 테이블 열에 매핑하고, 객체 간의 관계를 테이블 간의 외래 키 (Foreign Key)로 매핑하는 작업이 이루어진다. </div><br />

 <div> ⇒ 요약: 여기서 매핑이란 DB와 객체 사이 정보가 오갈 수 있게 조정해주는 역할</div><br />



</li>
</ul>
<ul>
<li><p><strong>이때 도메인(domain)이란?</strong></p>
  <div>→ 도메인은 일반적으로 특정 주제나 범위를 나타낸다.</div><br />

  <div>→ 개발자의 영역에선 도메인은 소프트웨어에서 특정 문제 영역이나 비지니스 영역을 가르킨다. 소프트웨어 개발자들은 특정 도메인의 문제를 해결하고자 하는데, 이때 해당 도메인의 규칙, 용어, 개념들을 이해하고 구현해야 한다.</div><br />

<ul>
<li>Domain Model: 도메인 모델은 특정 비지니스 도메인 구조와 규칙을 나타내는 추상화된 모델을 의미한다. 이는 해당 도메인에서 발생하는 주요 Entity, Aggregate, Value Object등을 포함한다.<br /><br /><ol>
<li>Entity: 식별 가능한 개체로, 시스템에서 추적하고 관리해야하는 중요한 개념이다. 예를 들어 온라인 상점에서 ‘상품 (Product)’나 ‘주문(Order)’이 Entity가 될 수 있다.<br /><br /></li>
<li>Aggregate: 연관된 Entity들의 그룹으로, 특정 규칙에 따라 하나의 루트 Entity를 중심으로 관리된다. Aggregate는 도메인 모델을 단순화 하고 복잡성을 관리하는데 도움이 된다.<br /><br /></li>
<li>Value Object: 값 자체가 중요한 개념으로, 식별자 대신 속성들의 조합으로 구성된다. 예를 들어 좌표나 날짜 범위가 Value Object가 될 수 있다.<br /></li>
<li>Domain Service: 특정 도메인 로직을 수행하는 서비스로, Entity나 Aggregate에서 제공하기 어려운 특수한 기능을 처리한다.<br /><br /></li>
<li>Domain Event: 도메인에서 중요한 사건을 나태나는 이벤트로, 시스템 내부에서 상태 변경을 통지하거나 외부 시스템과의 통합에 사용된다.<br /></li>
</ol>
</li>
</ul>
</li>
</ul>
<br>
<br>


<h2 id="주요-특징-및-개념">주요 특징 및 개념</h2>
<hr>
<ol>
<li>객체-관계 매핑: JPA는 자바 객체와 데이터베이스 테이블 간의 매핑을 지원한다. 즉, 자바 객체를 데이터베이스 레코드로 자동으로 변환해주는 ORM 기능을 제공한다.</li>
<li>Entity: JPA에서는 데이터베이스의 테이블을 나타내는 Entity를 정의한다. 각 엔터티는 자바 클래스로 표현되며, 이 클래스의 인스턴스는 데이터 베이스 레코드에 매핑된다.</li>
<li>Entity Manager: JPA는 Entity 객체를 관리하는데 사용되는 Entity Manager을 제공한다. Entity Manager을 통해 데이터베이스에 대한 CRUD연산을 수행할 수 있다.</li>
<li>JPAL (Java Persistence Query Language): SQL과 유사한 JPAL을 사용하여 데이터베이스에 대한 쿼리를 작성할 수 있다. 하지만 JPQL은 테이블이 아닌 Entity 객체에 기반하므로 객체 지향적인 쿼리 작성이 가능하다.</li>
<li>Transaction: JAP는 트랜잭션을 관리하여 데이터베이스 연산의 일관성을 보장한다. 트랜잭션을 시작하고 커밋 또는 롤백을 수행할 수 있다.</li>
</ol>
<br>
<br>

<h2 id="orm-object-relational-mapping">ORM (Object-Relational Mapping)</h2>
<h3 id="정의-1">정의</h3>
<hr>
<p>객체와 관계형 데이터 베이스 간의 매핑을 의미한다. 이는 객체 지향 프로그래밍 언어에서 사용되는 <strong>객체</strong>와 데이터베이스 <strong>테이블</strong> 사이의 관계를 매핑하는 기술이다. ORM을 사용하면 데이터베이스에서 직접 SQL 쿼리를 작성하는 대신, 객체 지향 프로그래밍 언어에서 제공하는 메서드와 속성을 사용하여 데이터베이스를 다룰 수 있다. 이를 통해 개발자는 데이터베이스와의 상호 작용을 더 추상화하고, 코드를 더 간결하게 작성할 수 있다. </p>
<h3 id="특징">특징</h3>
<hr>
<p>개발 생산성을 향상시키고 코드의 유지보수성을 높일 수 있다. ORM 프레임워크를 사용하면 데이터베이스와의 상호 작용을 추상화하여 더 효율적으로 코드를 작성하고 유지보수 할 수 있다.</p>
<h3 id="종류">종류</h3>
<hr>
<ol>
<li>Hibernate: Java 언어를 기반으로 하는 ORM 프레임워크로, Java 객체와 관계형 데이터베이스 간의 매핑을 제공한다.</li>
<li>Entity Framework: .NET 프레임워크의 일부로, C# 등의 언어를 사용하는 애플리케이션에서 관계형 데이터 베이스와의 상호 작용을 단순화하는 ORM 프레임워크이다.</li>
<li>Django ORM: Python 웹 프레임워크인 Django에서 제공되는 ORM으로, Python 언어로 개발된 웹 애플리케이션에서 데이터 베이스를 다루는 데 사용된다.</li>
</ol>
<br>
<br>


<h2 id="entity">Entity</h2>
<h3 id="정의-2">정의</h3>
<hr>
<p>JPA에서 데이터베이스의 테이블과 매핑되는 자바 객체를 나타낸다.</p>
<h3 id="예시코드-1">예시코드 1</h3>
<hr>
<pre><code class="language-jsx">import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    private Long id; // Person 테이블의 기본키
    private String name;
    private int age;

    // 기본 생성자, 게터/세터 등 필요한 메서드 작성
}</code></pre>
<ul>
<li><code>@Entity</code> 어노테이션은 이 클래스가 JPA Entity임을 나타낸다</li>
<li>@Id 어노테이션은 해당 필드가 데이터베이스의 기본키 (primary key)에 매핑되는 것을 나타낸다.</li>
</ul>
<h3 id="예시코드-2">예시코드 2</h3>
<hr>
<pre><code class="language-jsx">package com.example.domain;

import com.example.controller.request.CommentRequest;
import com.example.controller.request.PostRequest;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Setter
@NoArgsConstructor
@Getter
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name=&quot;title&quot;, columnDefinition = &quot;varchar(20)&quot;, nullable = false)
    private String title;
    @Column(name=&quot;content&quot;, columnDefinition = &quot;text&quot;, nullable = false)
    private String content;
    @Column(name=&quot;is_anonymous&quot;, columnDefinition = &quot;boolean&quot;, nullable = false)
    private Boolean isAnonymous = true;
    @CreationTimestamp
    @Column(name = &quot;created_date&quot;, columnDefinition = &quot;TIMESTAMP&quot;)
    private LocalDateTime createdDate;
    @UpdateTimestamp
    @Column(name = &quot;last_modified_date&quot;, columnDefinition = &quot;TIMESTAMP&quot;)
    private LocalDateTime lastModifiedDate;

    @OneToMany(mappedBy = &quot;post&quot;, fetch = FetchType.EAGER)
    private List&lt;Comment&gt; commentList=new ArrayList&lt;&gt;();
    public static Post from(PostRequest postRequest) {
        Post post = new Post();
        post.setTitle(postRequest.getTitle());
        post.setContent(postRequest.getContent());

        // 명시적으로 isAnonymous 값을 설정하며, null일 경우 기본값인 false로 설정합니다.
        post.setIsAnonymous(postRequest.getIsAnonymous() != null ? postRequest.getIsAnonymous() : false);

        return post;
    }

    public Comment addComment(CommentRequest commentRequest) {
        Comment comment = new Comment();
        comment.setContent(commentRequest.getContent());
        comment.setIsAnonymous(commentRequest.getIsAnonymous());
        comment.setPost(this);
        return comment;
    }
}</code></pre>
<ol>
<li>Entity 어노테이션 및 클래스 선언</li>
</ol>
<pre><code class="language-jsx">@Entity
@Setter
@NoArgsConstructor
@Getter
public class Post {
    // 클래스 내용
}</code></pre>
<ul>
<li><code>@Setter, @NoArgsConstructor, @Getter:</code> Lombok 어노테이션으로 Getter, Setter, 기본생성자를 자동으로 생성한다.</li>
</ul>
<ol>
<li>필드 정의</li>
</ol>
<pre><code class="language-jsx">@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name=&quot;title&quot;, columnDefinition = &quot;varchar(20)&quot;, nullable = false)
private String title;
@Column(name=&quot;content&quot;, columnDefinition = &quot;text&quot;, nullable = false)
private String content;
@Column(name=&quot;is_anonymous&quot;, columnDefinition = &quot;boolean&quot;, nullable = false)
private Boolean isAnonymous = true;
@CreationTimestamp
@Column(name = &quot;created_date&quot;, columnDefinition = &quot;TIMESTAMP&quot;)
private LocalDateTime createdDate;
@UpdateTimestamp
@Column(name = &quot;last_modified_date&quot;, columnDefinition = &quot;TIMESTAMP&quot;)
private LocalDateTime lastModifiedDate;</code></pre>
<ul>
<li><code>@Id:</code> 기본키를 나타낸다.</li>
<li><code>@GeneratedValue:</code> 기본키의 자동 생성 전략을 지정한다.</li>
<li><code>@Column:</code> 데이터베이스 컬럼에 대한 매핑 정보를 제공한다.</li>
</ul>
<ol>
<li>OneToMany 관계</li>
</ol>
<pre><code class="language-jsx">@OneToMany(mappedBy = &quot;post&quot;, fetch = FetchType.EAGER)
private List&lt;Comment&gt; commentList=new ArrayList&lt;&gt;();</code></pre>
<ul>
<li><code>@OneToMany:</code> ’Post’ 엔티티가 여러 개의 ‘Comment’ 엔티티를 가질 수 있다.</li>
<li><code>mappedBy = post:</code> ’Comment’ 클래스에서 ‘post’ 필드에 의해 매핑된다는 것을 의미한다. 다시 말해, ‘Comment’ 엔티티에 있는 ‘post’ 필드로 연결된다.</li>
<li><code>fetch = FetchType.EAGER:</code> ’fetch’속성은 데이터를 어떻게 가져올지 설정한다. ‘FetchType.Eager’은 관련 엔티티를 즉시 로딩하라는 것을 의미한다. 즉, ‘Post’엔터티를 조회할 때 함게 연관된 모든 ‘Comment’엔터티도 가져오게 된다.</li>
</ul>
<p>→ 이 부분을 통해 ‘Post’ 엔터티를 조회할 때 해당 ‘Post’에 대한 모든 댓글 (’Comment’)도 함께 가져오게 된다. EAGER 로딩은 한 번에 모든 데이터를 가져오기 때문에 성능상의 이슈가 발생할 수 있으므로 신중하게 사용하는 것이 중요하다. 만약 성능상의 문제가 있을 경우, <code>FetchType.Lazy</code> 를 통해 필요한 시점에 데이터를 가져오도록 설정할 수 있다.</p>
<p>3-1. ManyToOne 관계</p>
<pre><code class="language-jsx">@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = &quot;post_id&quot;, nullable = false)
private Post post;</code></pre>
<ul>
<li><code>@ManyToOne:</code> 여러개의 ‘Comment’ 엔티티 하나의 ‘Post’ 엔티티에 속한다는 것을 나타낸다.</li>
<li><code>@JoinColumn:</code>외래 키(Foreign Key)를 매핑하는 데 사용된다.</li>
<li><code>nullable = false:</code> 이 필드는 null이 될 수 없다는 것을 나타낸다. 다시 말해 ‘Commnet’는 항상 특정 ‘Post’에 속해야 한다.</li>
</ul>
<p>→ 이 관계 설정을 통해 ‘Comment’ 엔티티는 특정 ‘Post’ 엔티티에 속하게 된다.</p>
<ol>
<li>정적 팩토리 메서드 (’from’ 메서드)</li>
</ol>
<pre><code class="language-jsx">public static Post from(PostRequest postRequest) {
    Post post = new Post();
    // 내용 생략
    return post;
}</code></pre>
<ul>
<li>‘form’ 메서드는 ‘PostRequest’ 객체를 받아 ‘Post’ 객체로 변환하는 정적 팩토리 메서드 이다.</li>
</ul>
<ol>
<li>댓글 추가 메서드 (’addComment’ 메서드)</li>
</ol>
<pre><code class="language-jsx">gpublic Comment addComment(CommentRequest commentRequest) {
    Comment comment = new Comment();
    // 내용 생략
    return comment;
}</code></pre>
<ul>
<li>addComment’메서드는 ‘CommentRequest’ 객체를 받아 새로운 객체를 생성하고, 이를 현재 ‘Post’ 객체에 추가한다.</li>
</ul>
<br>
<br>

<h2 id="entitymanager">EntityManager</h2>
<h3 id="정의-3">정의</h3>
<hr>
<p>JPA에서 Entity 객체(생명주기)를 관리하고 데이터베이스와의 상호작용을 담당하는 인터페이스 이다</p>
<h3 id="주요-기능">주요 기능</h3>
<hr>
<ol>
<li>Entity Management: ‘EntityManager’은 Entity의 생명주기를 관리한다. Entity를 데이터베이스에 저장하거나 데이터베이스에서 조회, 수정, 삭제할 때 사용된다.<br /><br /></li>
<li>Transaction Management: JPA에서 DB 조작은 트랜잭션 내에서 이루어져야 한다. ‘EntityManager’은 트랜잭션을 시작하고 커밋 또는 롤백하는 기능을 제공한다. 이를 통해 일관성 있는 데이터베이스 조작을 보장한다.<br /><br /></li>
<li>쿼리 수행 (Query Execution): JPAdptjsms JPAL(Java Persistence Query Language)라는 객체 지향적인 쿼리를 제공한다. ‘EntityManager’을 사용하여 JPQL을 실행하고 데이터베이스로부터 결과를 가져올 수 있다.<br /><br /></li>
<li>영속성 컨텍스트 (Persistence Context): ‘EntityManager’은 영속성 컨텍스트를 관리한다. 영속성 컨텍스트는 Entity 객체의 상태를 추적하고, 객체 간의 관계를 유지하는데 사용된다. 변경된 Entity는 트랜잭션 커밋 시에 데이터베이스에 반영된다.</li>
</ol>
<ul>
<li><p><strong>이때 생명주기란?</strong></p>
<p>  <br />→ “생명주기”는 어던 개체나 시스템이 처음 생성되어 시작되고, 일정한 주기를 거쳐 성장하고 변경되며, 마지막으로 소멸되는 과정을 나타낸다. 객체, 소프트웨어 애플리케이션, 생물체, 하드웨어 등 다양한 컨텍스트에서 사용된다.<br /><br /></p>
<p>  → 객체의 생성주기는 객체가 생성되고 메모리에 할당된 시점부터 사용되고 변경되며, 더 이상 필요하지 않아 소멸될 때까지의 과정을 나타낸다. 이러한 과정을 객체의 생성, 초기화, 사용, 변경, 소멸 단계로 구성될 수 있다.<br /><br /></p>
<p>  → 소프트웨어 애플리케이션의 생명주기는 개발, 테스트, 배포, 운영, 유지보수 등의 단계로 나눌 수 있다. 이러한 단계를 통해 애플리케이션은 계속해서 발전하고 변화하며, 필요에 따라 업데이트 되거나 개선된다.<br /><br /></p>
<p>  → 컴퓨터 시스템의 생명주기는 하드웨어나 소프트웨어의 설계, 제조, 사용, 유지보수, 폐끼까지의 주기를 나타낸다.</p>
</li>
<li><p><strong>이때 트랜잭션 (Transaction)이란?</strong></p>
<p>  → 트랜잭션은 DB의 상태를 변화시키기 위해서 수행되어야 하는 작업의 단위를 뜻한다.</p>
<p>  → 트랜잭션은 ACID 속성을 따라야 한다</p>
<ol>
<li><p>원자성 (Atomicity): 트랜잭션의 모든 작업은 원자 단위로 처리되어야 하며, 모든 작업이 성공적으로 완료되거나 실패하면 롤백되어야 한다. 즉, 모든 작업이 성공하거나 아무것도 수행되지 않아야 한다.</p>
</li>
<li><p>일관성 (Consistenc): 트랜잭션이 완료된 후에도 데이터베이스는 일관된 상태여야 한다. 트랜잭션이 일어나기 전과 후에 데이터베이스의 무결성이 유지되어야 한다.</p>
</li>
<li><p>고립성 (Isolation): 여러 트랜잭션이 동시에 실행되더라도 각 트랜잭션은 서로 영향을 미치지 않고 독립적으로 수행되는 것처럼 보여야 한다. 한 트랜잭션의 부분 결과가 다른 트랜잭션에 노출되어서는 안 된다.</p>
</li>
<li><p>지속성 (Durability): 트랜잭션이 성공적으로 완료되면 해당 변경 내용은 영구적으로 데이터베이스에 반영되어야 하며, 시스템 장애 발생 시에도 유지되어야 한다.</p>
<p>→ 트랜잭션은 주로 데이터베이스에서 데이터의 무결성을 보장하고 일관성을 유지하기 위해 사용된다. 개발자는 트랜잭션을 사용하여 여러 작업을 우너자적으로 실행하고 DB를 안정적으로 유지할 수 있다.</p>
</li>
</ol>
</li>
</ul>
<br>
<br>

<h2 id="계층형-구조">계층형 구조</h2>
<p><img src="https://3513843782-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LxjHkZu4T9MzJ5fEMNe%2Fsync%2F654da041d496907baf37d960608c6885d2c66edc.png?generation=1621425019389979&alt=media" alt=""></p>
<div style="display: flex; flex-direction: row; align-items: flex-start;">
    <div style="flex: 1;">
        <img src="https://velog.velcdn.com/images/red_truth/post/137b32b3-af62-4faf-aead-8ac977f3dd4c/image.png" alt="이미지 설명">
    </div>
    <div style="flex: 1; margin-top:20px;">
      <ul>
            <li>controller, web: 웹 계층</li>
            <li>service: 비지니스 로직, 트랜잭션 처리</li>
            <li>repository: JPA를 직접 사용하는 계층, Entity Manager 사용</li>
            <li>domain: Entity가 모여있는 계층, 모든 계층에서 사용</li>
        </div>
            </ul>
    </div>
</div>






<p>참고자료: <a href="https://dodeon.gitbook.io/study/kimyounghan-spring-boot-and-jpa-development/03-architecture">https://dodeon.gitbook.io/study/kimyounghan-spring-boot-and-jpa-development/03-architecture</a></p>
]]></description>
        </item>
    </channel>
</rss>