<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>eleven_ill.log</title>
        <link>https://velog.io/</link>
        <description>포토폴리오 https://wikidocs.net/book/10969 유튜브 링크 https://www.youtube.com/@%EC%B5%9C%EC%9B%90%EC%9D%BC-n5r</description>
        <lastBuildDate>Thu, 12 Mar 2026 14:22:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>eleven_ill.log</title>
            <url>https://velog.velcdn.com/images/eleven_ill/profile/de07b90d-6859-415d-8561-3ea43cea6293/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. eleven_ill.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/eleven_ill" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[리액트 네이티브 Expo vs CLI로 프로젝트 실행하기]]></title>
            <link>https://velog.io/@eleven_ill/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-Expo-vs-CLI%EB%A1%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-Expo-vs-CLI%EB%A1%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 12 Mar 2026 14:22:56 GMT</pubDate>
            <description><![CDATA[<h3 id="react-native-cli-프로젝트-실행-방법">React Native CLI 프로젝트 실행 방법</h3>
<p>1️⃣ 프로젝트 폴더 이동
<code>cd 프로젝트폴더</code>
2️⃣ 의존성 설치
<code>npm install</code>
🤖 Android 실행
<code>npx react-native run-android</code></p>
<p>이 명령어가 React Native CLI 프로젝트 실행 명령어입니다.</p>
<p>동작 과정은 대략 이렇습니다.</p>
<ol>
<li><p>Gradle 빌드</p>
</li>
<li><p>APK 생성</p>
</li>
<li><p>에뮬레이터 또는 연결된 기기에 설치</p>
</li>
<li><p>앱 실행</p>
</li>
</ol>
<p>🍎 iOS 실행 (Mac만 가능)
<code>npx react-native run-ios</code>
📌 Expo vs React Native CLI 실행 명령어 차이
종류    실행 명령어</p>
<p>Expo                <code>npx expo start</code>
Expo (native build)    <code>npx expo run:android</code>
React Native CLI    <code>npx react-native run-android</code></p>
<p>🔎 프로젝트가 Expo인지 CLI인지 확인하는 방법
Expo 프로젝트 특징</p>
<pre><code>app.json
expo</code></pre><p>package.json</p>
<pre><code>&quot;dependencies&quot;: {
  &quot;expo&quot;: &quot;~50.0.0&quot;
}</code></pre><p>React Native CLI 특징</p>
<p>폴더 구조</p>
<pre><code>android/
ios/</code></pre><p>package.json</p>
<pre><code>&quot;dependencies&quot;: {
  &quot;react-native&quot;: &quot;0.73.x&quot;
}</code></pre><p>💡 추가로 하나 알려드리면 (중요)
실무에서 git clone 받은 프로젝트 실행할 때 90%는 아래 순서입니다.</p>
<pre><code>git clone &lt;repo&gt;
cd project
npm install
npx react-native run-android</code></pre><h3 id="react-native-cli-기기-연결-이후-시작하는-법">React Native CLI 기기 연결 이후 시작하는 법</h3>
<p>1️⃣ npx react-native run-android (일반적으로 사용하는 것)
<code>npx react-native run-android</code></p>
<p>이 명령어는 내부적으로 다음을 자동으로 다 합니다.</p>
<p>Metro bundler 실행 (JS 서버)</p>
<p>Android 앱 빌드 (Gradle)</p>
<p>연결된 기기 또는 에뮬레이터에 APK 설치</p>
<p>앱 실행</p>
<p>👉 그래서 실제 기기를 USB로 연결했다면 보통 이거 하나만 실행하면 끝입니다.</p>
<p>2️⃣ npx react-native start
<code>npx react-native start</code></p>
<p>이건 Metro Bundler(React Native JS 서버) 만 실행합니다.</p>
<p>역할</p>
<p>JS 코드 번들링</p>
<p>Hot reload</p>
<p>앱에서 JS 가져오는 서버</p>
<p>즉 앱을 설치하거나 실행하지는 않습니다.</p>
<p>3️⃣ 실제 개발할 때 많이 쓰는 방식
처음 실행할 때
<code>npx react-native run-android</code>
이후 Metro만 따로 실행할 때
<code>npx react-native start</code></p>
<p>그리고 Android Studio나 이미 설치된 앱에서 실행.</p>
<p>📱 실제 기기 연결 후 권장 순서</p>
<p>1️⃣ 기기 연결 확인</p>
<p><code>adb devices</code></p>
<p>기기가 나오면 OK</p>
<pre><code>List of devices attached
R3CT12345 device</code></pre><p>2️⃣ 앱 실행</p>
<p><code>npx react-native run-android</code></p>
<p>💡 React Native 처음 공부할 때 가장 헷갈리는 핵심</p>
<p>명령어    역할
<code>npx react-native start</code>    JS 서버만 실행
<code>npx react-native run-android</code>    빌드 + 설치 + 실행</p>
<p>👉 그래서 보통은 run-android만 사용합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rMateChart 데이터의 값의 차이가 클때 클]]></title>
            <link>https://velog.io/@eleven_ill/rMateChart-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-%EA%B0%92%EC%9D%98-%EC%B0%A8%EC%9D%B4%EA%B0%80-%ED%81%B4%EB%95%8C-%ED%81%B4</link>
            <guid>https://velog.io/@eleven_ill/rMateChart-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-%EA%B0%92%EC%9D%98-%EC%B0%A8%EC%9D%B4%EA%B0%80-%ED%81%B4%EB%95%8C-%ED%81%B4</guid>
            <pubDate>Thu, 25 Sep 2025 15:53:41 GMT</pubDate>
            <description><![CDATA[<p>지금 상황은 데이터 값이 너무 작아서 실제 차트에 그려지는 bar(또는 column)가 눈에 안 보이거나 클릭하기 어려운 수준이라 이벤트를 못 잡는 문제군요.
rMateChartH5에서는 몇 가지 접근법이 가능합니다.</p>
<p>🔹 해결 방법 1: minFieldWidth / minFieldHeight 사용</p>
<p>Column/Bar 계열 차트의 경우 Column2DSeries, Bar2DSeries 같은 시리즈에
minFieldWidth 또는 minFieldHeight 속성을 주면, 값이 작더라도 최소한의 두께가 보장됩니다.</p>
<p><Column2DSeries
    yField="QTY"
    displayName="수량"
    minFieldHeight="5"
    showDataTips="true"/></p>
<p>👉 이렇게 하면 QTY가 100이든 1이든 최소 5px 높이로 그려져서 클릭이 가능해집니다.</p>
<p>🔹 해결 방법 2: ItemRenderer 확장해서 투명 클릭 영역 만들기</p>
<p>값이 너무 작으면 클릭하기 힘드니까, hitTest를 확장해서 투명하게 클릭 가능한 공간을 넓혀주는 방식을 씁니다.</p>
<pre><code class="language-javascript">var ExtColumn2DItemRenderer = rMateChartH5.Column2DItemRenderer.extend({
    // hitTest 확장
    hitTest: function(x, y){
        var bounds = this.getBounds();
        // 세로 기준 최소 20px은 클릭 가능하게 확대
        if(bounds.height &lt; 20){
            var centerY = bounds.y + bounds.height/2;
            bounds.y = centerY - 10;
            bounds.height = 20;
        }
        return bounds.contains(x, y);
    }
});</code></pre>
<p>그리고 차트에서 시리즈에 itemRenderer를 지정:</p>
<pre><code>&lt;Column2DSeries
    yField=&quot;QTY&quot;
    displayName=&quot;수량&quot;
    itemRenderer=&quot;ExtColumn2DItemRenderer&quot;/&gt;</code></pre><p>👉 실제 바가 작게 그려져도 hitTest가 넓게 잡히니까 클릭 이벤트가 발생합니다.</p>
<p>🔹 해결 방법 3: 라벨 클릭으로 이벤트 트리거</p>
<p>만약 작은 bar는 보이지 않더라도, 카테고리 이름(CATEGORY) 라벨은 항상 보이죠.
X축 라벨을 클릭했을 때 chartClick을 실행하게 하면 됩니다.</p>
<pre><code class="language-javascript">chart.addEventListener(&quot;labelClick&quot;, function(event){
    var category = event.labelText;
    var rowData = chartData.find(d =&gt; d.CATEGORY === category);
    chartClick(&quot;series1&quot;, category, event.index, rowData, [rowData[&quot;QTY&quot;], category]);
});</code></pre>
<p>👉 이렇게 하면 라벨 클릭만으로도 해당 데이터 이벤트 실행이 가능합니다.</p>
<p>✅ 정리</p>
<p>가장 간단한 방법: minFieldHeight 속성 추가 → 작은 값도 최소 클릭 가능.</p>
<p>좀 더 확실하게: ItemRenderer hitTest 확장 → 투명 클릭 영역 확보.</p>
<p>차선책: X축 라벨 클릭 이벤트 연결 → bar가 안 보이더라도 데이터 이벤트 처리 가능.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rMate TreeMap 예시]]></title>
            <link>https://velog.io/@eleven_ill/rMate-TreeMap-%EC%98%88%EC%8B%9C</link>
            <guid>https://velog.io/@eleven_ill/rMate-TreeMap-%EC%98%88%EC%8B%9C</guid>
            <pubDate>Sun, 17 Aug 2025 15:22:01 GMT</pubDate>
            <description><![CDATA[<p>Treemap은 <code>nameField</code>(타일 이름), <code>weightField</code>(타일 크기 기준값) 구조여야 하는데, 지금은 <code>aaa</code>, <code>bbb</code>, <code>ccc</code>가 컬럼으로 분리돼 있어서 그대로는 쓰기 어렵울 경우.</p>
<hr>
<h2 id="📌-현재-쿼리-구조">📌 현재 쿼리 구조</h2>
<pre><code>Xname | aaa  | bbb  | ccc
------|------|------|-----
test1 | 1000 | 500  | 700
test2 | 2000 | 1500 | 700
test3 | 800  | 300  | 200
</code></pre><p>➡️ 이건 행(Row) 기준이 아니라 열(Column) 기준이라서 Treemap에서 직접 쓰기 힘듭니다.</p>
<hr>
<h2 id="📌-treemap-차트에-맞는-데이터-구조">📌 Treemap 차트에 맞는 데이터 구조</h2>
<p>Treemap은 <strong>항목 이름 + 값</strong> 형태가 기본이에요. 예를 들어:</p>
<pre><code>Xname | category | value
------|----------|------
test1 | aaa      | 1000
test1 | bbb      | 500
test1 | ccc      | 700
test2 | aaa      | 2000
test2 | bbb      | 1500
test2 | ccc      | 700
test3 | aaa      | 800
test3 | bbb      | 300
test3 | ccc      | 200
</code></pre><p>이렇게 만들어야 <code>nameField=&quot;category&quot;</code>, <code>weightField=&quot;value&quot;</code>, <code>groupField=&quot;Xname&quot;</code> 같은 식으로 사용할 수 있습니다.</p>
<hr>
<h2 id="📌-수정된-sql-예시-unpivot-방식">📌 수정된 SQL 예시 (UNPIVOT 방식)</h2>
<pre><code class="language-sql">SELECT Xname, category, value
FROM (
    SELECT &#39;test1&#39; as Xname, 1000 as aaa, 500 as bbb, 700 as ccc FROM dual
    UNION ALL
    SELECT &#39;test2&#39;, 2000, 1500, 700 FROM dual
    UNION ALL
    SELECT &#39;test3&#39;, 800, 300, 200 FROM dual
) t
UNPIVOT (
    value FOR category IN (aaa, bbb, ccc)
);
</code></pre>
<hr>
<h2 id="📌-rmate-treemap-예제-코드">📌 rMate Treemap 예제 코드</h2>
<pre><code class="language-xml">&lt;rMateChart&gt;
    &lt;Options&gt;
        &lt;Caption text=&quot;Treemap 예제&quot;/&gt;
        &lt;Legend/&gt;
    &lt;/Options&gt;
    &lt;TreeMapChart showDataTips=&quot;true&quot;&gt;
        &lt;series&gt;
            &lt;TreeMapSeriesnameField=&quot;category&quot;
                weightField=&quot;value&quot;
                groupField=&quot;Xname&quot;
                displayName=&quot;Treemap&quot;/&gt;
        &lt;/series&gt;
    &lt;/TreeMapChart&gt;
&lt;/rMateChart&gt;
</code></pre>
<hr>
<p>✅ 정리</p>
<ul>
<li>지금 쿼리처럼 <code>aaa, bbb, ccc</code>가 <strong>컬럼</strong>으로 나눠진 구조는 Treemap에 바로 적용 불가</li>
<li><code>UNPIVOT</code> 또는 <code>UNION ALL</code>로 <strong>행(row) 기반 데이터 구조</strong>로 변환 필요</li>
<li><code>nameField=category</code>, <code>weightField=value</code>, <code>groupField=Xname</code> 식으로 연결</li>
</ul>
<h2 id="📌-unpivot-없는-버전-쿼리">📌 UNPIVOT 없는 버전 쿼리</h2>
<pre><code class="language-sql">SELECT &#39;test1&#39; AS Xname, &#39;aaa&#39; AS category, 1000 AS value FROM dual
UNION ALL
SELECT &#39;test1&#39;, &#39;bbb&#39;, 500 FROM dual
UNION ALL
SELECT &#39;test1&#39;, &#39;ccc&#39;, 700 FROM dual

UNION ALL
SELECT &#39;test2&#39;, &#39;aaa&#39;, 2000 FROM dual
UNION ALL
SELECT &#39;test2&#39;, &#39;bbb&#39;, 1500 FROM dual
UNION ALL
SELECT &#39;test2&#39;, &#39;ccc&#39;, 700 FROM dual

UNION ALL
SELECT &#39;test3&#39;, &#39;aaa&#39;, 800 FROM dual
UNION ALL
SELECT &#39;test3&#39;, &#39;bbb&#39;, 300 FROM dual
UNION ALL
SELECT &#39;test3&#39;, &#39;ccc&#39;, 200 FROM dual;
</code></pre>
<hr>
<h2 id="📊-결과-데이터">📊 결과 데이터</h2>
<pre><code>Xname  | category | value
-------|----------|------
test1  | aaa      | 1000
test1  | bbb      | 500
test1  | ccc      | 700
test2  | aaa      | 2000
test2  | bbb      | 1500
test2  | ccc      | 700
test3  | aaa      | 800
test3  | bbb      | 300
test3  | ccc      | 200
</code></pre><hr>
<h2 id="📌-rmate-treemap-매핑">📌 rMate Treemap 매핑</h2>
<pre><code class="language-xml">&lt;TreeMapChart showDataTips=&quot;true&quot;&gt;
    &lt;series&gt;
        &lt;TreeMapSeriesnameField=&quot;category&quot;
            weightField=&quot;value&quot;
            groupField=&quot;Xname&quot;
            displayName=&quot;Treemap&quot;/&gt;
    &lt;/series&gt;
&lt;/TreeMapChart&gt;
</code></pre>
<hr>
<p>✅ 이렇게 하면 <code>test1</code>, <code>test2</code>, <code>test3</code> 그룹별로 묶이고,</p>
<p>그 안에서 <code>aaa/bbb/ccc</code>가 사각형으로 표현되며, 값(<code>value</code>) 크기 비율로 타일 크기가 달라집니다.</p>
<h3 id="총-test123별로-3개의-큰-treemap박스에-한-덩어리마다-aaabbbccc타일을-넣고-싶은-경우에-아래와-같이-작성">총 test1,2,3별로 3개의 큰 treemap박스에 한 덩어리마다 aaa,bbb,ccc타일을 넣고 싶은 경우에, 아래와 같이 작성</h3>
<p>이런 구조라면 rMate Treemap의 <strong><code>groupField</code></strong> 속성을 쓰면 됩니다.</p>
<p>말씀하신 건 크게 보면</p>
<ul>
<li><strong>그룹</strong> : <code>test1</code>, <code>test2</code>, <code>test3</code> (큰 박스)</li>
<li><strong>타일</strong> : <code>aaa</code>, <code>bbb</code>, <code>ccc</code> (작은 사각형)</li>
<li><strong>크기</strong> : <code>value</code> (숫자 값 기준으로 타일 면적이 달라짐)</li>
</ul>
<hr>
<h2 id="📊-데이터-구조">📊 데이터 구조</h2>
<p>앞서 만든 <strong>UNION ALL 버전</strong>이 그대로 적합합니다:</p>
<pre><code>Xname  | category | value
-------|----------|------
test1  | aaa      | 1000
test1  | bbb      | 500
test1  | ccc      | 700
test2  | aaa      | 2000
test2  | bbb      | 1500
test2  | ccc      | 700
test3  | aaa      | 800
test3  | bbb      | 300
test3  | ccc      | 200
</code></pre><hr>
<h2 id="📌-rmate-treemap-예제-코드-1">📌 rMate Treemap 예제 코드</h2>
<pre><code class="language-xml">&lt;rMateChart&gt;
    &lt;Options&gt;
        &lt;Caption text=&quot;Treemap 예제&quot;/&gt;
        &lt;Legend/&gt;
    &lt;/Options&gt;

    &lt;TreeMapChart showDataTips=&quot;true&quot;&gt;
        &lt;series&gt;
            &lt;TreeMapSeriesgroupField=&quot;Xname&quot;      &lt;!-- 큰 그룹 --&gt;
                nameField=&quot;category&quot;    &lt;!-- 작은 타일 이름 --&gt;
                weightField=&quot;value&quot;     &lt;!-- 타일 크기 기준 --&gt;
                displayName=&quot;Treemap&quot;/&gt;
        &lt;/series&gt;
    &lt;/TreeMapChart&gt;
&lt;/rMateChart&gt;
</code></pre>
<hr>
<p>✅ 이렇게 하면</p>
<ul>
<li>화면에 <strong>3개의 큰 박스(test1, test2, test3)</strong> 가 생기고,</li>
<li>각 박스 안에 <strong>aaa, bbb, ccc 타일</strong>이 들어갑니다.</li>
<li>각 타일의 면적은 <code>value</code> 값에 따라 비율로 표시돼요.</li>
</ul>
<hr>
<p>👉 여기서 선택사항:</p>
<ul>
<li><code>labelField=&quot;category&quot;</code> 옵션을 주면 타일 안에 aaa/bbb/ccc 글자 표시 가능</li>
<li><code>colorField</code> 같은 속성을 추가하면 aaa/bbb/ccc 별로 색상 다르게 표현 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[rMate 속성 정리]]></title>
            <link>https://velog.io/@eleven_ill/rMate-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@eleven_ill/rMate-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 17 Aug 2025 15:05:57 GMT</pubDate>
            <description><![CDATA[<p>rMate Chart에서 <strong>Waterfall, Treemap, Bar 차트</strong>에서 자주 쓰이는 속성(<code>legend</code>, <code>series</code>, <code>displayName</code>, <code>nameField</code>, <code>weightField</code>, <code>xField</code>, <code>yField</code>)의 의미</p>
<hr>
<h2 id="📌-1-legend">📌 1. legend</h2>
<ul>
<li><strong>범례(legend)</strong> 영역을 표시할지 여부 및 속성 정의.</li>
<li>보통 차트 종류(series)나 데이터 항목 구분을 설명하는 부분.</li>
<li>예: <code>legendDirection</code>, <code>legendLabelPlacement</code>, <code>useVisibleCheck</code> 등 세부 옵션 존재.</li>
</ul>
<hr>
<h2 id="📌-2-series">📌 2. series</h2>
<ul>
<li>차트에 표시되는 <strong>데이터 계열(Series)</strong> 정의.</li>
<li><code>BarSeries</code>, <code>WaterfallSeries</code>, <code>TreeMapSeries</code> 등 차트 종류에 맞는 series를 지정해야 함.</li>
<li><code>series</code> 내부에 <code>xField</code>, <code>yField</code>, <code>displayName</code> 같은 속성이 포함됨.</li>
</ul>
<hr>
<h2 id="📌-3-displayname">📌 3. displayName</h2>
<ul>
<li><strong>범례(legend)</strong> 또는 <strong>툴팁(toolTip)</strong> 에 표시될 이름.</li>
<li>데이터셋의 필드명이 그대로 나오지 않게, 사람이 읽기 좋은 이름으로 표시할 때 사용.</li>
</ul>
<pre><code class="language-xml">&lt;BarSeries yField=&quot;sales&quot; displayName=&quot;매출액&quot;/&gt;
</code></pre>
<hr>
<h2 id="📌-4-namefield">📌 4. nameField</h2>
<ul>
<li><strong>TreemapSeries 전용</strong> 속성.</li>
<li>각 사각형(타일)에 표시될 이름을 지정.</li>
<li>예를 들어 부서명, 카테고리명 등.</li>
</ul>
<pre><code class="language-xml">&lt;TreeMapSeries nameField=&quot;deptName&quot; weightField=&quot;sales&quot;/&gt;
</code></pre>
<hr>
<h2 id="📌-5-weightfield">📌 5. weightField</h2>
<ul>
<li><strong>TreemapSeries 전용</strong> 속성.</li>
<li>사각형의 크기를 결정하는 기준값.</li>
<li>값이 클수록 넓은 영역을 차지.</li>
</ul>
<pre><code class="language-xml">&lt;TreeMapSeries nameField=&quot;deptName&quot; weightField=&quot;sales&quot;/&gt;
</code></pre>
<hr>
<h2 id="📌-6-xfield--yfield">📌 6. xField / yField</h2>
<ul>
<li><strong>Bar, Column, Waterfall 등 좌표형 차트에서 축 데이터 지정.</strong></li>
<li><code>xField</code> : X축에 해당하는 값 (보통 카테고리/분류, 예: 월, 제품명 등)</li>
<li><code>yField</code> : Y축에 해당하는 값 (보통 수치형 데이터, 예: 매출액, 건수 등)</li>
</ul>
<pre><code class="language-xml">&lt;BarSeries xField=&quot;month&quot; yField=&quot;sales&quot;/&gt;
&lt;WaterfallSeries xField=&quot;step&quot; yField=&quot;amount&quot;/&gt;
</code></pre>
<hr>
<h2 id="📊-차트별-정리">📊 차트별 정리</h2>
<table>
<thead>
<tr>
<th>차트종류</th>
<th>주요 필드</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Waterfall</strong></td>
<td><code>xField</code>, <code>yField</code>, <code>displayName</code></td>
<td>X축 단계별 값, Y축 증감 값, 범례 표시 이름</td>
</tr>
<tr>
<td><strong>Treemap</strong></td>
<td><code>nameField</code>, <code>weightField</code>, <code>displayName</code></td>
<td>사각형 타일 이름, 크기 비율, 범례 이름</td>
</tr>
<tr>
<td><strong>Bar</strong></td>
<td><code>xField</code>, <code>yField</code>, <code>displayName</code></td>
<td>X축 카테고리, Y축 값, 범례 이름</td>
</tr>
</tbody></table>
<hr>
<p>👉 정리</p>
<ul>
<li><strong>legend</strong> = 범례 표시 여부/설정</li>
<li><strong>series</strong> = 어떤 데이터 계열(차트 종류) 쓸지</li>
<li><strong>displayName</strong> = 범례/툴팁에 표시되는 이름</li>
<li><strong>nameField</strong> = Treemap에서 각 사각형 이름</li>
<li><strong>weightField</strong> = Treemap에서 크기 기준값</li>
<li><strong>xField, yField</strong> = 좌표형 차트에서 축 데이터</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[rMate차트를 구성하기 위한 html 파일 구조]]></title>
            <link>https://velog.io/@eleven_ill/rMate%EC%B0%A8%ED%8A%B8%EB%A5%BC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-html-%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@eleven_ill/rMate%EC%B0%A8%ED%8A%B8%EB%A5%BC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-html-%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Sun, 10 Aug 2025 08:25:59 GMT</pubDate>
            <description><![CDATA[<ul>
<li><strong>백엔드(Spring)</strong>: <code>Controller → Service → ServiceImpl → DAO → DAOImpl → xml</code> (DB 조회)</li>
<li><strong>프론트(Nexacro)</strong>: <code>testfilter.xfdl</code>, <code>testview.xfdl</code></li>
<li><strong>목표</strong>: <code>filter</code>에서 조건 선택 → <code>view</code>에서 rMate 차트로 시각화</li>
</ul>
<p>여기서 rMate Chart for HTML5를 Nexacro에 넣으려면, 보통 Nexacro의 <code>HTML5 컴포넌트</code>를 활용해서 <strong>별도의 HTML 파일</strong>을 로드하는 방식이 필요합니다.</p>
<p>즉,  <strong>HTML *<em>파일이 추가로 필요하며, Nexacro에서 차트를 보여줄 *</em>브리지 역할</strong>을 합니다.</p>
<hr>
<h2 id="1-추가로-필요한-파일">1. 추가로 필요한 파일</h2>
<ol>
<li><strong>rMateChart.html</strong><ul>
<li>rMate Chart 스크립트와 차트 설정이 포함된 HTML 파일</li>
<li>Nexacro의 <code>WebBrowser</code> 컴포넌트에서 이 HTML을 불러와 차트를 표시</li>
<li>HTML 내부에서 <code>rMateChartH5.create()</code>로 차트 객체 생성</li>
<li>Nexacro에서 전달받은 데이터(JSON 등)를 <code>setData()</code>로 반영</li>
</ul>
</li>
<li><strong>(선택) 차트 데이터 가공용 JavaScript 파일</strong><ul>
<li>rMateChart.html 내부에 직접 써도 되지만, 유지보수를 위해 외부 <code>.js</code>로 분리 가능</li>
</ul>
</li>
</ol>
<hr>
<h2 id="2-파일-구성-예시">2. 파일 구성 예시</h2>
<pre><code>/src/main/java/com/example/controller/TestChartController.java
/src/main/java/com/example/service/TestChartService.java
/src/main/java/com/example/service/impl/TestChartServiceImpl.java
/src/main/java/com/example/dao/TestChartDAO.java
/src/main/java/com/example/dao/impl/TestChartDAOImpl.java
/src/main/resources/mapper/TestChartMapper.xml

/nexacro_ui/testfilter.xfdl
/nexacro_ui/testview.xfdl
/nexacro_ui/html/rMateChart.html  ← 신규 추가
/nexacro_ui/js/rMateChartHelper.js (선택)
</code></pre><hr>
<h2 id="3-동작-흐름">3. 동작 흐름</h2>
<h3 id="①-filter-화면-testfilterxfdl">① Filter 화면 (<code>testfilter.xfdl</code>)</h3>
<ul>
<li>사용자가 조건(날짜, 제품코드 등) 선택 → 버튼 클릭 시</li>
<li>해당 조건을 <strong>Transaction</strong>으로 Controller에 전달</li>
<li>Controller에서 조건에 맞는 데이터 조회</li>
<li>결과를 View화면의 Dataset에 반영</li>
</ul>
<pre><code class="language-jsx">// testfilter.xfdl
function btn_search_onclick(obj,e) {
    var sDate = this.cal_from.value;
    var eDate = this.cal_to.value;

    var args = &quot;fromDate=&quot; + sDate + &quot; toDate=&quot; + eDate;

    this.transaction(
        &quot;searchChart&quot;,              // ID
        &quot;svc::getChartData.do&quot;,     // URL
        &quot;&quot;,                         // inDataset
        &quot;ds_chart=out_chart&quot;,       // outDataset
        args,                       // arguments
        &quot;fn_callback&quot;
    );
}

function fn_callback(svcID, errCD, errMsg) {
    if(svcID == &quot;searchChart&quot; &amp;&amp; errCD == 0) {
        // View 화면 Dataset에 복사
        var objView = this.parent.form_testview;
        objView.ds_chart.copyData(this.ds_chart, true);
    }
}
</code></pre>
<hr>
<h3 id="②-view-화면-testviewxfdl">② View 화면 (<code>testview.xfdl</code>)</h3>
<ul>
<li>WebBrowser 컴포넌트에 <code>rMateChart.html</code> 로드</li>
<li>Dataset 변경 시 HTML에 데이터 전달</li>
</ul>
<pre><code class="language-jsx">// testview.xfdl
function form_onload(obj,e) {
    this.webChart.set_url(&quot;http://localhost:8080/nexacro_ui/html/rMateChart.html&quot;);
}

function ds_chart_onrowposchanged(obj,e) {
    if (this.webChart.getProperty(&quot;document&quot;) != null) {
        var jsonData = this.ds_chart.saveXML();
        this.webChart.callMethod(&quot;setChartData&quot;, jsonData);
    }
}
</code></pre>
<hr>
<h3 id="③-rmatecharthtml">③ rMateChart.html</h3>
<ul>
<li>Nexacro에서 호출할 수 있는 <code>setChartData()</code> 함수 구현</li>
<li>rMate Chart 스크립트 로드 후, 데이터 세팅</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;script src=&quot;./rMateChartH5.js&quot;&gt;&lt;/script&gt;
    &lt;script&gt;
        var chart;

        window.onload = function() {
            rMateChartH5.create(&quot;chart1&quot;, &quot;chartHolder&quot;, &quot;&quot;, &quot;100%&quot;, &quot;100%&quot;);
        };

        function setChartData(xmlData) {
            var jsonData = parseNexacroXML(xmlData); // XML → Array 변환
            chart.setData(jsonData);
        }
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=&quot;chartHolder&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<hr>
<h2 id="4-핵심-포인트">4. 핵심 포인트</h2>
<ul>
<li><strong>HTML 파일</strong>이 반드시 필요 (Nexacro WebBrowser에서 로드)</li>
<li>Nexacro Dataset → HTML로 전달 → rMateChart에 적용</li>
<li><code>Filter</code>와 <code>View</code>는 Dataset으로 연동 (copyData 등)</li>
<li>Controller ~ DAO는 기존 데이터 조회 구조 그대로 사용 가능</li>
<li>rMate는 JSON이나 Array 데이터를 선호하니 XML은 변환 필요</li>
</ul>
<hr>
<p>원하시면 제가 <strong>Spring + Nexacro + rMateChart HTML 연동 전체 샘플 구조</strong>를 바로 만들어서 드릴 수 있습니다.</p>
<p>그러면 파일별 실제 코드가 전부 연결된 상태로 보여줄 수 있어요.</p>
<p>지금처럼 설명만 하는 것보다 훨씬 이해가 빠를 겁니다.</p>
<p>이대로 전체 예제 구성까지 해드릴까요?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[차트 구성을 위한 spring 기본 구조]]></title>
            <link>https://velog.io/@eleven_ill/%EC%B0%A8%ED%8A%B8-%EA%B5%AC%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-spring-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@eleven_ill/%EC%B0%A8%ED%8A%B8-%EA%B5%AC%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-spring-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Thu, 07 Aug 2025 14:54:13 GMT</pubDate>
            <description><![CDATA[<h3 id="1-controller">1. <strong>Controller</strong></h3>
<pre><code class="language-java">@Controller
public class ChartController {

    @Resource(name = &quot;chartService&quot;)
    private ChartService chartService;

    @RequestMapping(&quot;/chart/data.do&quot;)
    @ResponseBody
    public NexacroResult getChartData() {
        List&lt;Map&lt;String, Object&gt;&gt; chartList = chartService.selectChartData();

        NexacroResult result = new NexacroResult();
        result.addDataSet(&quot;output&quot;, chartList);  // Dataset 이름과 일치해야 함

        return result;
    }
}
</code></pre>
<hr>
<h3 id="2-service--dao">2. <strong>Service &amp; DAO</strong></h3>
<h3 id="chartservicejava">ChartService.java</h3>
<pre><code class="language-java">public interface ChartService {
    List&lt;Map&lt;String, Object&gt;&gt; selectChartData();
}
</code></pre>
<h3 id="chartserviceimpljava">ChartServiceImpl.java</h3>
<pre><code class="language-java">@Service(&quot;chartService&quot;)
public class ChartServiceImpl implements ChartService {

    @Resource(name = &quot;chartDAO&quot;)
    private ChartDAO chartDAO;

    @Override
    public List&lt;Map&lt;String, Object&gt;&gt; selectChartData() {
        return chartDAO.selectChartData();
    }
}
</code></pre>
<h3 id="chartdaojava">ChartDAO.java</h3>
<pre><code class="language-java">public interface ChartDAO {
    List&lt;Map&lt;String, Object&gt;&gt; selectChartData();
}
</code></pre>
<h3 id="chartdaoimpljava">ChartDAOImpl.java</h3>
<pre><code class="language-java">@Repository(&quot;chartDAO&quot;)
public class ChartDAOImpl implements ChartDAO {

    @Autowired
    private SqlSession sqlSession;

    private static final String NAMESPACE = &quot;chartMapper.&quot;;

    @Override
    public List&lt;Map&lt;String, Object&gt;&gt; selectChartData() {
        return sqlSession.selectList(NAMESPACE + &quot;selectChartData&quot;);
    }
}
</code></pre>
<hr>
<h3 id="3-mybatis-mapper">3. <strong>MyBatis Mapper</strong></h3>
<pre><code class="language-xml">&lt;select id=&quot;selectChartData&quot; resultType=&quot;map&quot;&gt;
    SELECT
        MONTH_NAME AS category,
        SALES_AMOUNT AS value
    FROM SALES_TABLE
    ORDER BY MONTH_NO
&lt;/select&gt;
</code></pre>
<ul>
<li><code>resultType=&quot;map&quot;</code> → 자동으로 Map 형태로 반환됨</li>
</ul>
<hr>
<h3 id="4-넥사크로-dataset과-매칭">4. <strong>넥사크로 Dataset과 매칭</strong></h3>
<table>
<thead>
<tr>
<th>category (문자)</th>
<th>value (숫자)</th>
</tr>
</thead>
<tbody><tr>
<td>1월</td>
<td>100</td>
</tr>
<tr>
<td>2월</td>
<td>120</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
</tbody></table>
<p>넥사크로에서 이 데이터를 그대로 <code>WebBrowser.callMethod()</code>로 넘기면 차트에서 사용 가능해.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Map, List, Set 비교하기]]></title>
            <link>https://velog.io/@eleven_ill/Map-List-Set-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/Map-List-Set-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 14 Jul 2025 14:56:10 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-1-map-list-set-비교">✅ 1. <code>Map</code>, <code>List</code>, <code>Set</code> 비교</h2>
<h3 id="🔹-공통점">🔹 공통점</h3>
<ul>
<li>모두 <strong>컬렉션 프레임워크</strong>의 일부이며, 데이터를 담는 컨테이너입니다.</li>
<li>하지만 용도와 특징이 다릅니다.</li>
</ul>
<hr>
<h3 id="📊-주요-차이점-요약">📊 주요 차이점 요약</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th><code>List</code></th>
<th><code>Set</code></th>
<th><code>Map</code></th>
</tr>
</thead>
<tbody><tr>
<td>기본 구조</td>
<td>순서 있는 데이터 집합</td>
<td>순서 없는 유일한 데이터 집합</td>
<td>키(key)-값(value) 쌍</td>
</tr>
<tr>
<td>중복 허용</td>
<td>O (중복 가능)</td>
<td>X (중복 불가)</td>
<td>키: X, 값: O</td>
</tr>
<tr>
<td>순서 유지</td>
<td>O (인덱스로 접근 가능)</td>
<td>구현체에 따라 다름 (<code>HashSet</code>: 무순서, <code>LinkedHashSet</code>: 순서 유지)</td>
<td>구현체에 따라 다름</td>
</tr>
<tr>
<td>대표 클래스</td>
<td><code>ArrayList</code>, <code>LinkedList</code></td>
<td><code>HashSet</code>, <code>TreeSet</code></td>
<td><code>HashMap</code>, <code>TreeMap</code></td>
</tr>
<tr>
<td>접근 방식</td>
<td>인덱스로 접근</td>
<td>값 자체로 확인</td>
<td>키로 접근</td>
</tr>
</tbody></table>
<hr>
<h3 id="🔸-사용-예">🔸 사용 예</h3>
<h3 id="✅-list">✅ List</h3>
<pre><code class="language-java">
List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add(&quot;apple&quot;);
list.add(&quot;banana&quot;);
list.add(&quot;apple&quot;); // 중복 허용
System.out.println(list); // [apple, banana, apple]
</code></pre>
<h3 id="✅-set">✅ Set</h3>
<pre><code class="language-java">
Set&lt;String&gt; set = new HashSet&lt;&gt;();
set.add(&quot;apple&quot;);
set.add(&quot;banana&quot;);
set.add(&quot;apple&quot;); // 중복 무시됨
System.out.println(set); // [apple, banana] (순서는 보장 X)
</code></pre>
<h3 id="✅-map">✅ Map</h3>
<pre><code class="language-java">
Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
map.put(&quot;apple&quot;, 1);
map.put(&quot;banana&quot;, 2);
map.put(&quot;apple&quot;, 3); // 기존 키 덮어씀
System.out.println(map); // {banana=2, apple=3}
</code></pre>
<hr>
<h2 id="✅-2-제네릭-클래스-만들기">✅ 2. 제네릭 클래스 만들기</h2>
<blockquote>
<p>직접 타입을 파라미터로 받는 클래스를 만들 수 있어요. T, E, K, V 등을 자주 사용합니다.</p>
</blockquote>
<hr>
<h3 id="🔹-기본-구조">🔹 기본 구조</h3>
<pre><code class="language-java">
public class Box&lt;T&gt; {
    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }
}
</code></pre>
<hr>
<h3 id="🔹-사용-예">🔹 사용 예</h3>
<pre><code class="language-java">
public class Main {
    public static void main(String[] args) {
        Box&lt;String&gt; stringBox = new Box&lt;&gt;();
        stringBox.set(&quot;Hello&quot;);
        System.out.println(stringBox.get());  // Hello

        Box&lt;Integer&gt; intBox = new Box&lt;&gt;();
        intBox.set(100);
        System.out.println(intBox.get());  // 100
    }
}
</code></pre>
<hr>
<h3 id="🔹-여러-개-타입-지정도-가능">🔹 여러 개 타입 지정도 가능</h3>
<pre><code class="language-java">
public class Pair&lt;K, V&gt; {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() { return key; }
    public V getValue() { return value; }
}
</code></pre>
<h3 id="사용-예">사용 예</h3>
<pre><code class="language-java">
Pair&lt;String, Integer&gt; pair = new Pair&lt;&gt;(&quot;apple&quot;, 3);
System.out.println(pair.getKey());   // apple
System.out.println(pair.getValue()); // 3
</code></pre>
<hr>
<h2 id="✅-요약-정리">✅ 요약 정리</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>List</code></td>
<td>순서 있음, 중복 허용, 인덱스로 접근</td>
</tr>
<tr>
<td><code>Set</code></td>
<td>순서 없음, 중복 불가</td>
</tr>
<tr>
<td><code>Map</code></td>
<td>키-값 쌍 저장, 키는 유일</td>
</tr>
<tr>
<td>제네릭 클래스</td>
<td>타입을 외부에서 지정 가능, 형변환 없이 사용 가능, 타입 안정성 제공</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Collection과 Generic이란?]]></title>
            <link>https://velog.io/@eleven_ill/Collection%EA%B3%BC-Generic%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@eleven_ill/Collection%EA%B3%BC-Generic%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Mon, 14 Jul 2025 14:13:50 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-1-collection-컬렉션">✅ 1. <strong>Collection (컬렉션)</strong></h2>
<blockquote>
<p>&quot;데이터(객체)를 효율적으로 저장하고 관리하기 위한 자료 구조 클래스들의 집합&quot;</p>
</blockquote>
<h3 id="🔹-종류">🔹 종류</h3>
<p>Java에서 <code>Collection</code>은 인터페이스이며, 주요 하위 인터페이스와 구현 클래스는 다음과 같습니다:</p>
<table>
<thead>
<tr>
<th>인터페이스</th>
<th>설명</th>
<th>대표 구현 클래스</th>
</tr>
</thead>
<tbody><tr>
<td><code>List</code></td>
<td>순서 있고, 중복 허용</td>
<td><code>ArrayList</code>, <code>LinkedList</code></td>
</tr>
<tr>
<td><code>Set</code></td>
<td>순서 없음, 중복 불가</td>
<td><code>HashSet</code>, <code>TreeSet</code></td>
</tr>
<tr>
<td><code>Queue</code></td>
<td>FIFO 구조의 처리</td>
<td><code>LinkedList</code>, <code>PriorityQueue</code></td>
</tr>
<tr>
<td><code>Map</code></td>
<td>키-값 쌍 저장 (※ Collection 아님)</td>
<td><code>HashMap</code>, <code>TreeMap</code></td>
</tr>
</tbody></table>
<h3 id="🔹-예시">🔹 예시</h3>
<pre><code class="language-java">
List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add(&quot;apple&quot;);
list.add(&quot;banana&quot;);
System.out.println(list); // [apple, banana]
</code></pre>
<hr>
<h2 id="✅-2-generic-제네릭">✅ 2. <strong>Generic (제네릭)</strong></h2>
<blockquote>
<p>&quot;클래스나 메서드에서 사용할 데이터 타입을 코드 작성 시가 아니라 사용할 때 지정하는 기법&quot;</p>
</blockquote>
<p>즉, 다양한 타입에 대해 <strong>타입 안정성(safety)</strong>을 보장하며 재사용 가능한 코드 작성이 가능해져요.</p>
<h3 id="🔹-왜-사용하나">🔹 왜 사용하나?</h3>
<ol>
<li><strong>타입 안정성</strong>: 잘못된 타입 저장 방지</li>
<li><strong>형변환 없이</strong> 바로 사용 가능</li>
<li><strong>코드 재사용성</strong> 증가</li>
</ol>
<h3 id="🔹-예시-1">🔹 예시</h3>
<pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add(&quot;hello&quot;);
// list.add(123); // 컴파일 에러 발생 (타입 안전성)
String s = list.get(0); // 형변환 불필요
</code></pre>
<hr>
<h2 id="✅-3-collection과-generic-함께-사용">✅ 3. <strong>Collection과 Generic 함께 사용</strong></h2>
<p>제네릭은 <strong>Collection에서 가장 많이 사용</strong>됩니다.</p>
<h3 id="🔹-예시-제네릭-없는-코드-비추천">🔹 예시: 제네릭 없는 코드 (비추천)</h3>
<pre><code class="language-java">List list = new ArrayList();
list.add(&quot;text&quot;);
list.add(123);  // 다른 타입도 들어갈 수 있음
String s = (String) list.get(0); // 형변환 필요
</code></pre>
<h3 id="🔹-예시-제네릭-사용한-코드-추천">🔹 예시: 제네릭 사용한 코드 (추천)</h3>
<pre><code class="language-java">List&lt;String&gt; list = new ArrayList&lt;&gt;();
list.add(&quot;text&quot;);
// list.add(123); // 컴파일 에러
String s = list.get(0); // 형변환 X
</code></pre>
<hr>
<h2 id="✅-예제-종합">✅ 예제 종합</h2>
<pre><code class="language-java">
import java.util.*;

public class Example {
    public static void main(String[] args) {
        List&lt;Integer&gt; nums = new ArrayList&lt;&gt;();
        nums.add(10);
        nums.add(20);

        for (Integer num : nums) {
            System.out.println(num * 2);  // 타입 안정성 보장
        }
    }
}
</code></pre>
<hr>
<h2 id="📌-요약">📌 요약</h2>
<table>
<thead>
<tr>
<th>개념</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Collection</strong></td>
<td>데이터를 저장/관리하는 자료구조 (List, Set, Map 등)</td>
</tr>
<tr>
<td><strong>Generic</strong></td>
<td>클래스/메서드의 타입을 매개변수로 일반화해서 코드 재사용 및 타입 안전성 보장</td>
</tr>
<tr>
<td><strong>둘의 관계</strong></td>
<td>대부분의 Collection 클래스는 Generic을 함께 사용함 (<code>List&lt;String&gt;</code>처럼)</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[넥사크로 getColumn, setColumn]]></title>
            <link>https://velog.io/@eleven_ill/%EB%84%A5%EC%82%AC%ED%81%AC%EB%A1%9C-getColumn-setColumn</link>
            <guid>https://velog.io/@eleven_ill/%EB%84%A5%EC%82%AC%ED%81%AC%EB%A1%9C-getColumn-setColumn</guid>
            <pubDate>Sun, 06 Jul 2025 15:22:53 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-개념-요약">✅ 개념 요약</h2>
<table>
<thead>
<tr>
<th>함수명</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td><code>getColumn(row, columnID)</code></td>
<td>특정 <strong>행(row)</strong>, <strong>컬럼(columnID)</strong>의 값을 가져옴</td>
</tr>
<tr>
<td><code>setColumn(row, columnID, value)</code></td>
<td>특정 <strong>행(row)</strong>, <strong>컬럼(columnID)</strong>의 값을 설정</td>
</tr>
<tr>
<td>- <code>row</code>: 정수형 인덱스 (0부터 시작)</td>
<td></td>
</tr>
<tr>
<td>- <code>columnID</code>: 컬럼명 (문자열)</td>
<td></td>
</tr>
<tr>
<td>- <code>value</code>: 설정할 값</td>
<td></td>
</tr>
</tbody></table>
<hr>
<h2 id="✅-예시-dataset">✅ 예시 Dataset</h2>
<pre><code>ds_user

-------------------------
id     | name   | age
-------------------------
1      | 철수   | 20
2      | 영희   | 22
</code></pre><hr>
<h2 id="✅-getcolumn-예제-값-가져오기">✅ getColumn 예제 (값 가져오기)</h2>
<pre><code class="language-jsx">
// Dataset ds_user의 0번째 행에서 name 값을 가져오기
var userName = ds_user.getColumn(0, &quot;name&quot;);  // &quot;철수&quot;
</code></pre>
<hr>
<h2 id="✅-setcolumn-예제-값-설정하기">✅ setColumn 예제 (값 설정하기)</h2>
<pre><code class="language-jsx">
// Dataset ds_user의 1번째 행의 age를 25로 수정
ds_user.setColumn(1, &quot;age&quot;, 25);
</code></pre>
<p>이후 <code>ds_user</code>의 상태는 아래와 같음:</p>
<pre><code>
id     | name   | age
-------------------------
1      | 철수   | 20
2      | 영희   | 25  &lt;-- 바뀜
</code></pre><hr>
<h2 id="✅-실무-사용-예제-버튼-클릭-시-값-변경">✅ 실무 사용 예제 (버튼 클릭 시 값 변경)</h2>
<pre><code class="language-jsx">// 버튼 클릭 이벤트에 연결된 함수
function btn_changeAge_onclick(obj, e)
{
    var row = ds_user.findRow(&quot;name&quot;, &quot;영희&quot;);  // 영희가 있는 행 찾기
    if(row &gt;= 0) {
        ds_user.setColumn(row, &quot;age&quot;, 30);  // 나이를 30으로 변경
    }
}
</code></pre>
<hr>
<h2 id="✅-팁-getcolumn-vs-getcolumntext">✅ 팁: getColumn vs getColumnText</h2>
<table>
<thead>
<tr>
<th>함수</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>getColumn</code></td>
<td>원시 값 가져오기 (숫자, 날짜 등 그대로)</td>
</tr>
<tr>
<td><code>getColumnText</code></td>
<td>화면에 표시되는 문자열 값 가져오기 (콤보박스 등 표시값 포함)</td>
</tr>
</tbody></table>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[spring 구조 이해하기]]></title>
            <link>https://velog.io/@eleven_ill/spring-%EA%B5%AC%EC%A1%B0-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/spring-%EA%B5%AC%EC%A1%B0-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 24 Jun 2025 14:33:42 GMT</pubDate>
            <description><![CDATA[<p>자바(Spring Framework 기반)에서의 Controller, Service, DAO 구조는 계층형 아키텍처 (Layered Architecture) 를 따르는 전형적인 설계입니다. 각 계층은 역할이 분리되어 유지보수성과 재사용성이 높습니다.</p>
<p><strong>🧭 전체 흐름 설명</strong></p>
<p><strong>1. Controller (컨트롤러)</strong></p>
<ul>
<li><p>클라이언트 요청을 받아 처리하고, 응답을 반환</p>
</li>
<li><p>Service 계층을 호출</p>
</li>
</ul>
<p><strong>2. Service (서비스 인터페이스)</strong></p>
<ul>
<li><p>비즈니스 로직을 정의 (인터페이스만 정의)</p>
</li>
<li><p>실제 로직은 ServiceImpl에서 구현</p>
</li>
</ul>
<p><strong>3. ServiceImpl (서비스 구현체)</strong></p>
<ul>
<li><p>Service 인터페이스를 구현</p>
</li>
<li><p>DAO 계층을 호출하여 데이터베이스 작업 수행</p>
</li>
</ul>
<p><strong>4. DAO (데이터 접근 인터페이스)</strong></p>
<ul>
<li>DB 접근 메서드 정의</li>
</ul>
<p><strong>5. DAOImpl (DAO 구현체)</strong></p>
<ul>
<li>실제 DB 연산을 수행 (JDBC, JPA 등으로 구현)</li>
</ul>
<p><strong>📁 디렉토리 구조 예시</strong></p>
<p>com.example.demo
├── controller
│   └── UserController.java
├── service
│   ├── UserService.java
│   └── UserServiceImpl.java
├── dao
│   ├── UserDAO.java
│   └── UserDAOImpl.java
└── model
    └── User.java</p>
<p><strong>💻 예제: 사용자 이름 조회 (UserController → UserService → UserDAO)</strong></p>
<p><strong>📌 1. User.java (모델)</strong></p>
<pre><code class="language-java">public class User {
    private int id;
    private String name;

    // 생성자, getter, setter
    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public int getId() { return id; }
    public String getName() { return name; }
}</code></pre>
<p><strong>📌 2. UserDAO.java (DAO 인터페이스)</strong></p>
<pre><code class="language-java">public interface UserDAO {
    User findUserById(int id);
}</code></pre>
<p><strong>📌 3. UserDAOImpl.java (DAO 구현체)</strong></p>
<pre><code class="language-java">import java.util.HashMap;
import java.util.Map;

public class UserDAOImpl implements UserDAO {
    private static final Map&lt;Integer, User&gt; userDb = new HashMap&lt;&gt;();

    static {
        userDb.put(1, new User(1, &quot;Alice&quot;));
        userDb.put(2, new User(2, &quot;Bob&quot;));
    }

    @Override
    public User findUserById(int id) {
        return userDb.get(id);
    }
}</code></pre>
<p><strong>📌 4. UserService.java (서비스 인터페이스)</strong></p>
<pre><code class="language-java">public interface UserService {
    String getUserNameById(int id);
}</code></pre>
<p><strong>📌 5. UserServiceImpl.java (서비스 구현체)</strong></p>
<pre><code class="language-java">public class UserServiceImpl implements UserService {
    private final UserDAO userDAO = new UserDAOImpl();

    @Override
    public String getUserNameById(int id) {
        User user = userDAO.findUserById(id);
        return user != null ? user.getName() : &quot;사용자 없음&quot;;
    }
}</code></pre>
<p><strong>📌 6. UserController.java (컨트롤러)</strong></p>
<pre><code class="language-java">import java.util.Scanner;

public class UserController {
    private final UserService userService = new UserServiceImpl();

    public void getUserName() {
        Scanner scanner = new Scanner(System.in);
        System.out.print(&quot;사용자 ID를 입력하세요: &quot;);
        int id = scanner.nextInt();

        String name = userService.getUserNameById(id);
        System.out.println(&quot;사용자 이름: &quot; + name);
    }

    public static void main(String[] args) {
        UserController controller = new UserController();
        controller.getUserName();
    }
}</code></pre>
<p><strong>✅ 실행 결과 예시</strong></p>
<p>사용자 ID를 입력하세요: 1
사용자 이름: Alice</p>
<p>*<em>🧩 요약
*</em></p>
<table>
<thead>
<tr>
<th align="left">계층</th>
<th align="left">클래스</th>
<th align="left">역할</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Controller</td>
<td align="left">UserController</td>
<td align="left">클라이언트 요청 처리</td>
</tr>
<tr>
<td align="left">Service</td>
<td align="left">UserService, UserServiceImpl</td>
<td align="left">비즈니스 로직 처리</td>
</tr>
<tr>
<td align="left">DAO</td>
<td align="left">UserDAO, UserDAOImpl</td>
<td align="left">DB 접근 로직 처리</td>
</tr>
<tr>
<td align="left">Model</td>
<td align="left">User</td>
<td align="left">데이터 객체</td>
</tr>
</tbody></table>
<p>이 구조는 Spring Framework에서도 동일하게 사용되며, 각 계층은 @Controller, @Service, @Repository 등의 애너테이션으로 정의됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리눅스 마스터 2급 핵심 개념]]></title>
            <link>https://velog.io/@eleven_ill/%EB%A6%AC%EB%88%85%EC%8A%A4-%EB%A7%88%EC%8A%A4%ED%84%B0-2%EA%B8%89-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@eleven_ill/%EB%A6%AC%EB%88%85%EC%8A%A4-%EB%A7%88%EC%8A%A4%ED%84%B0-2%EA%B8%89-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Mon, 03 Feb 2025 10:06:33 GMT</pubDate>
            <description><![CDATA[<h2 id="리눅스-마스터-2급을-준비하시는-많은-분들-아래-내용만-빠르게-암기하고-합격하세요">리눅스 마스터 2급을 준비하시는 많은 분들 아래 내용만 빠르게 암기하고 합격하세요!!</h2>
<p><strong>주요 암기 내용!!</strong></p>
<p>&lt;문제 해설&gt;</p>
<ol>
<li><p>/etc/bashrc : 모든 사용자에 적용되는 alias와 함수 설정</p>
</li>
<li><p>/etc/profile : 모든 사용자에 적용되는 환경변수와 시작관련 프로그램 설정 지정파일</p>
</li>
<li><p>~/.bashrc :개인 사용자가 정의한 alias와 함수들이 있는 파일</p>
</li>
<li><p>~/.bash_profile : 개인 사용자가 정의한  alias와 함수 설정파일</p>
</li>
</ol>
<p>standalone: 대기하고 있다가(메모리 상주) 요청이 발생하면 즉각 처리 (빈번한 요청이 발생하는 서비스에 적합)</p>
<p>inetd: 평상시에 잠자고 있다가 요청이 올 때만 구동 (메모리 관리가 효율적)</p>
<p>&lt;문제 해설&gt;1. jobs 명령어는 현재 셸 세션에서 실행된 백그라운드 작업의 상태를 보여주지만,셸 세션과 관련된 작업에 한정되므로 시스템 전체에서 실행 중인 데몬을 확인하는 데 사용할 수 없습니다.</p>
<ol start="2">
<li><p>fg 명령어는 백그라운드 작업을 포그라운드로 가져오는 데 사용되며, 데몬 확인에는 적합하지 않습니다.</p>
</li>
<li><p>bg 명령어는 정지된 작업을 백그라운드에서 계속 실행시키는 데 사용되지만, 실행 중인 데몬을 확인하는 데 사용되지 않습니다.</p>
</li>
<li><p>ps 명령어는 현재 시스템에서 실행 중인 모든 프로세스(데몬 포함)의 정보를 제공할 수 있으며,특정 조건에 맞는 프로세스를 검색하는 다양한 옵션을 제공합니다.</p>
</li>
</ol>
<hr>
<p>간단하고 정확하게 차이점 알려드립니다.</p>
<ol>
<li><p>백그라운드로 실행 중인 작업목록을 물어보면 =&gt; jobs</p>
</li>
<li><p>백그라운드로 실행 중인 데몬을 물어보면 =&gt; ps</p>
</li>
</ol>
<p>기출문제에선 보통 백그라운드는 jobs가 답인 경우가 많아서 앞에 문제만 보고 냅다 답을 jobs 찍는 분들이 많은데,</p>
<p>문제를 끝까지 읽고 &quot;작업목록 or 프로세스&quot;냐 데몬이냐를 확인 후 답을 고르세요.</p>
<p>&lt;문제 해설&gt;nice는 프로그램 실행 시 우선 순위를 결정하지만renice는 실행된 프로세스의 우선 순위를 결정하며renice는 nice와 다르게 PID값을 이용해 우선 순위를 결정하며,양수일 경우 n, 음수일 경우 -n을 사용합니다.nice는 양수일 경우 -n, 음수일 경우 --n을 사용합니다</p>
<hr>
<p>killall, nice -&gt; 프로세스명 사용 / kill,renice 프로세스번호 사용</p>
<p>.virc = 비주얼 모드인 vim을 위한 설정 파일</p>
<p>.exrc = vi 편집기에서 사용자가 환경 설정을 등록하는 파일</p>
<p>tar에서</p>
<p>cvf(create) - 생성</p>
<p>xvf(extratct) - 해제</p>
<p>tvf(list) - 목록</p>
<ul>
<li>-J : xzip</li>
<li>-j : bzip2</li>
<li>-z : gzip</li>
<li>-Z : compress</li>
</ul>
<p>&lt;문제 해설&gt;</p>
<p>LV (Logical Volume): 논리 볼륨은 사용자가 실제로 데이터를 저장하는 공간입니다. LVM을 사용하면 LV의 크기를 필요에 따라 쉽게 조정할 수 있으며, 여러 개의 물리적 디스크에 걸쳐 있을 수도 있습니다.</p>
<p>PV (Physical Volume): 물리 볼륨은 LVM에서 사용되는 가장 낮은 수준의 저장공간 단위입니다. 하나 이상의 하드 드라이브 파티션 또는 전체 디스크를 PV로 초기화하여 LVM에서 사용할 수 있게 합니다.</p>
<p>PE (Physical Extent): 물리적 확장은 PV 내에서 LV에 할당될 수 있는 고정된 크기의 데이터 블록입니다. PE는 LVM의 할당 단위로 작동합니다.</p>
<p>VG (Volume Group): 볼륨 그룹은 하나 이상의 PV를 묶어서 관리하는 논리적인 컨테이너입니다. VG 내에서 LV들을 생성하고 관리합니다.</p>
<p>10GB 디스크 4개 사용 시 각 RAID에 대한 설명.</p>
<p>RAID-0 : 스트라이핑의 경우 용량 모두 사용 40GB.</p>
<p>RAID-1 : 미러링의 경우 절반으로 줄어듦 20GB.</p>
<p>RAID-5 : 1개의 디스크 패리티로 사용 30GB.</p>
<p>RAID-6 : 2개의 디스크 패리티로 사용 20GB.</p>
<ol>
<li><p>데스크톱 환경 : 사용자가 그래픽 인터페이스를 통해 컴퓨터를 사용할 수 있도록 하는 전체 환경 (예: GNOME, KDE).</p>
</li>
<li><p>윈도 매니저 : 윈도우의 배치와 외관을 관리하는 시스템 소프트웨어 (예: Metacity, Openbox).</p>
</li>
<li><p>디스플레이 매니저 : 로그인 화면을 제공하고 사용자 세션을 시작하는 프로그램 (예: GDM, LightDM).</p>
</li>
<li><p>위젯 : 그래픽 사용자 인터페이스에서 사용되는 작은 독립형 컴포넌트 (예: 버튼, 텍스트 박스).</p>
</li>
</ol>
<p>Nautilus는 GNOME 데스크톱 환경에서 사용되는 파일 관리자</p>
<p>Metacity는 GNOME 데스크톱 환경에서 사용되는 윈도우 매니저</p>
<p>Mutter는 GNOME 3 데스크톱 환경에서 사용되는 윈도우 매니저</p>
<p>Plasma는 KDE 커뮤니티에 의해 개발된 데스크탑 환경.</p>
<ol>
<li><p>Docker : 컨테이너, 이미지 형태로 패키지 관리 및 배포 플랫폼</p>
</li>
<li><p>Openstack : 오픈 소스 클라우드컴퓨팅 플랫폼</p>
</li>
<li><p>Kubernetes : Docker 자동화 플랫폼</p>
</li>
<li><p>Ansible : 오픈 소스 자동화 플랫폼</p>
</li>
</ol>
<p>LAN (Local Area Network) : 상대적으로 좁은 지역. 집, 사무실, 학교 등</p>
<p>MAN (Metropolitan Area Network) : 상대적으로 LAN보다 넓은 지역. 큰 도시나 캠퍼스 같은 광역. 전화, TV, 인터넷은 MAN</p>
<p>SAN (Storage Area Network) : 저장 장치를 네트워크로 연결하는데 사용하는 개념.</p>
<p>WAN (Wide Area Network) : 상대적으로 매우 넓은 지역. 국가, 대륙, 전세계를 아우르는 개념.</p>
<p>netstat명령 옵션</p>
<ul>
<li>-r : 라우팅 테이블 표시</li>
<li>-t : TCP 연결 표시</li>
<li>-m : 소켓 버퍼의 메모리 사용상태 표시</li>
<li>-n : 주소와 포트번호 등을 숫자 형태로 표시</li>
</ul>
<p>물리 계층 - 리피터, 허브</p>
<p>데이터 링크 계층 - 스위치, 브리지</p>
<p>네트워크 계층 - 라우터</p>
<p>전송 계층 - 게이트 웨이</p>
<p>ICANN (Internet Corporation for Assigned Names and Numbers):</p>
<p>IP, 도메인 등 관리</p>
<p>IEEE (Institute of Electrical and Electronics Engineers):</p>
<p>LAN 규격, 다양한 컴퓨팅 표준 등</p>
<p>ITU-T (International Telecommunication Union - Telecommunication Standardization Sector):</p>
<p>통신 기술의 표준을 정립. 네트워크와 서비스의 표준을 개발</p>
<p>ISO (International Organization for Standardization):</p>
<p>국제 표준 개발 기구</p>
<p>NIS(Network Information Service) - 네트워크 정보를 중앙 집중식으로 유지하고 배포하는 서비스</p>
<p>SAMBA - Winodws 및 리눅스/UNIX 간의 파일 공유 및 네트워크 통합 용이</p>
<p>HTTP(Hypertext Transfer Protocol) - www에서 정보를 전송하는데 사용되는 프로토콜</p>
<p>게이트웨이 주소값 확인 가능 명령: ip, route, netstat</p>
<p>전송단위 1계층부터 4계층까지</p>
<p>비트 - 프레임 - 패킷 - 세그먼트</p>
<p>네트워크 계층: IP, ICMP, ARP, RARP</p>
<p>전송 계층: TCP, UDP</p>
<p>pico = Pine 이메일 클라이언트의 일부로 개발되었으나, 라이센스 이슈로 인해 nano로 대체</p>
<p>nano: GNU 프로젝트의 일부로 개발, 간단하고 사용자 친화적인 텍스트 편집기</p>
<p>vim = Vi 편집기의 확장된 버전</p>
<p>kwrite = KDE 데스크톱 환경의 일부로 개발된 텍스트 편집기</p>
<ol>
<li><p>Totem : GNOME 환경의 기본 동영상 플레이어</p>
</li>
<li><p>Evince : GNOME을 위해 설계된 문서 뷰어. PDF, Postscript 등.</p>
</li>
<li><p>Eog(Eye of GNOME) : GNOME 환경의 기본 이미지 뷰어.</p>
</li>
<li><p>Gimp(GNU Image Manipulation Program) : GNU에 의해 개발된 강력한 오픈 소스 이미지 편집 툴</p>
</li>
</ol>
<p>ss 명령어 옵션</p>
<ul>
<li>-n (number) : 주소 및 포트 번호를 숫자로 출력</li>
<li>-a (all) : 모든 소켓 정보를 출력</li>
<li>-ㅇ (time out) : 타임아웃 값을 지정</li>
<li>-t (tcp) : tcp 소켓 정보 출력</li>
</ul>
<p>ARP - IP에서 MAC</p>
<p>RARP - MAC에서 IP</p>
<p>quota: 사용자나 그룹의 디스크 사용량과 할당량(쿼터)을 보여줌.</p>
<p>edquota: 텍스트 에디터와 같은 환경에서 쿼터를 편집할 수 있게 해줌.</p>
<p>setquota: 명령줄에서 직접 쿼터를 설정하거나 수정하기 위해 사용.(보통 -u 옵션 사용하면 이거임.)</p>
<p>xfs_quota: XFS 파일 시스템에서 쿼터를 명령줄에서 설정함.(보통 -x -c 옵션 사용하면 이거임.)</p>
<p>fdisk</p>
<p>새로운 파티션 생성 / 기존 파티션 삭제 / 파티션의 타입 결정 등의 작업을 수행할 수 있음.</p>
<p>한번에 한 디스크에 대해서만 작업 수행</p>
<p>fdisk [옵션] [장치명]</p>
<p>p : 디스크 정보 표시</p>
<p>n : 파티션 생성</p>
<p>t : 파티션 속성 지정</p>
<p>d : 파티션 삭제</p>
<p>du: 디렉터리 별 디스크 사용량 확인</p>
<p>df : 마운트 된 하드 디스크의 사용량 확인(분할 된 파티션 별로 사용량 확인)</p>
<p>파티션 고유번호 uuid</p>
<p>확인하는 명령어 blkid</p>
<ol>
<li><p>LOGIN : 로그인 세션을 나타내는 쉘 환경변수</p>
</li>
<li><p>USER : 현재 사용자 이름을 나타내는 환경변수</p>
</li>
<li><p>SHELL : 현재 사용중인 쉘경로를 나타내는 환경변수</p>
</li>
<li><p>BASH : bash 쉘에 대한 정보를 나타내는 환경변수</p>
</li>
</ol>
<p>CentOS 7부터는 기존 init프로세스에서 systemd를 쓰기로함</p>
<p>그 이전은 init이고 PID는 1이다</p>
<p>nice -n [프로세스명]</p>
<p>killall [프로세스명]</p>
<p>renice 는 pid를 인자값으로 받습니다</p>
<p>kill 은 pid를 인자값으로 받습니다.</p>
<p>nano 편집기 단축키</p>
<p>[Ctrl] + [a] : 행의 맨 앞으로 커서 이동</p>
<p>[Ctrl] + [e] : 행의 맨 끝으로 커서 이동</p>
<p>[Ctrl] + [c] : 현재 커서 위치 문자의 ascii 값을 표시</p>
<p>[Ctrl] + [x] : 나노 편집기 종료, 변경사항 저장 여부 물어봄</p>
<p>vi편집기</p>
<p>① -c : 특정 명령어 실행</p>
<p>② -r : 이전에 편집 중이던 파일이 중단되거나 충돌로 인해 손실된 경우 복구</p>
<p>③ -R : 읽기 전용 모드(파일 읽을 수 있지만 수정 불가)</p>
<p>④ + : 파일을 열면서 커서를 특정 위치에 놓을 때 사용</p>
<p>vi 편집기에서</p>
<ul>
<li>-h : 커서를 한칸 왼쪽으로 이동하는 명령</li>
<li>-j : 커서를 한줄 아래로 이동하는 명령</li>
<li>-k : 커서를 한줄 위로 이동하는 명령</li>
<li>-l : 커서를 한칸 오른쪽으로 이동하는 명령</li>
</ul>
<p>RAID-0 : 스트라이핑 : 모든 디스크 사용</p>
<p>RAID-1 : 미러링 : 디스크 개수의 절반을 백업에 사용 그래서 최소 2개 필요</p>
<p>RAID-5 : 한 개의 패리티 드라이브 사용 (디스크 개수 -1 * 용량)</p>
<p>RAID-6 : 두 개의 패리티 드라이브 사용 (디스크 개수 -2 * 용량)</p>
<p>configure(환경설정) -&gt; make(컴파일) -&gt; make install</p>
<hr>
<p>압축효율</p>
<p>.xz &gt; .bz2 &gt; .gz &gt; .Z</p>
<p>압축해제명령어</p>
<ul>
<li>Jxvf : xz</li>
<li>jxvf : bzip2</li>
<li>zxvf : gzip</li>
<li>xvf : .tar</li>
</ul>
<p>Evince는 PDF 형식이나 포스트스크립트 형식의 문서를 그놈 데스크톱 환경에서 읽을 수 있는 소프트웨어이다</p>
<ul>
<li>ls: 현재 디렉토리에 있는 파일 및 디렉터리의 목록을 보여주는 명령어입니다. -l 옵션을 사용하면 자세한 목록이 표시되며, 이 목록에는 각 파일 또는 디렉터리의 소유자와 그룹이 표시됩니다.</li>
<li>chmod: 파일의 퍼미션을 변경하는 데 사용됩니다. 소유자를 확인하는 목적으로는 사용되지 않습니다.</li>
<li>chown: 파일이나 디렉터리의 소유자와 그룹을 변경하는 데 사용됩니다. 직접적으로 소유자를 확인하는 용도로 사용할 수 있습니다.</li>
<li>umask: 새로운 파일이나 디렉터리를 생성할 때 기본적으로 설정되는 퍼미션을 제어하는 데 사용됩니다. 소유자를 확인하는 용도로는 사용되지 않습니다.</li>
</ul>
<p>/etc/passwd 파일은 사용자 계정 정보를 포함</p>
<p>/etc/shells 파일은 시스템에서 사용 가능한 셸의 목록을 제공하는 파일</p>
<p>/etc/bashrc 파일은 Bash 셸의 전역 설정 파일로, 시스템 전체의 Bash 셸 설정을 구성</p>
<p>/etc/profile 파일은 사용자가 로그인할 때 실행되는 전역 프로파일 스크립트</p>
<p>온라인 패키지 관리 도구</p>
<p>dpkg는 기본 패키지 관리 도구 입니다. (온라인 아님 )</p>
<ol>
<li><p>dnf : 레드헷 계열인 yum 을 대체하는 온라인 패키지</p>
</li>
<li><p>zypper ; 수세 계열 온라인 패키지</p>
</li>
<li><p>apt-get : 데미안 계열 온라인 패키지</p>
</li>
</ol>
<p>소스 설치 방법 cmake 선택 프로젝트 - MySQL, KDE, LMMS</p>
<p>&lt;문제 해설&gt;</p>
<p>-Z: compress 압축 적용 옵션</p>
<p>-z: gzip 압축 적용 옵션.</p>
<p>-j: bzip2 압축 적용 옵션.</p>
<p>-J: xz 압축 적용 옵션.</p>
<p>압축률: compress&lt;gzip&lt;bz2&lt;xz</p>
<p>압축 파일 용량이 가장 큰 compress 방식이 마지막 알파벳의 대문자Z그 다음으로 압축이 덜되는 gz가 소문자z압축률이 제일 좋은 xz가 J이렇게 외워봅시다.</p>
<p>LVM의 구성 순서</p>
<p>PV - VG - LV</p>
<p>X Window 시스템에 할당된 TCP 포트 번호는 6000+</p>
<p>Xlib - XCB</p>
<p>KDE - Qt</p>
<p>GTK+ - GNOME</p>
<p>세트라고 외우시면 최소 한 문제는 먹고 들어갑니다.</p>
<p>IPv4 32bit</p>
<p>IPv6 128bit</p>
<p>MAC 48bit</p>
<p>ISO -&gt; OSI</p>
<p>EIA -&gt; LAN 케이블 관련 표준</p>
<p>IEEE -&gt; LAN 관련 표준</p>
<p>평문사용으로 보안에 취약하지면 원격 접속이 된다 = Telnet</p>
<p>보안강화가 되며 원격 접속이 된다 = SSH</p>
<p>전가상화 방식 : KVM</p>
<p>반가상화 방식 : Xen</p>
<p>Kubernetes : 컨테이너화된 애플리케이션의 &#39;자동&#39; 배포, 확장 및 &#39;관리&#39;를 위한 오픈 소스 플랫폼, 초기 구글 개발 -&gt; cncf 기증.</p>
<p>Docker : 경량화된 가상화기술 / 컨테이너화된 애플리케이션의 개발, 배포 및 실행(관련 키워드:XEN, KVM)</p>
<p>데비안 apt-get 명령어</p>
<p>purge = 환경설정까지 다 지움</p>
<p>remove = remove랑 erase는 동일한 기능 수행. 환경설정파일은 남겨둠.</p>
<p>erase = remove</p>
<p>delete = 유효하지 않은 명령어</p>
<p>dnf - 페도라 온라인 패키지 관리 도구</p>
<p>rpm - 레드햇 오프라인 패키지 관리 도구</p>
<p>zypper - 수세 온라인 패키지 관리 도구</p>
<p>apt-get - 데비안 온라인 패키지 관리 도구</p>
<ol>
<li><p>/etc/bashrc : 모든 사용자에 적용되는 alias와 함수 설정</p>
</li>
<li><p>/etc/profile : 모든 사용자에 적용되는 환경변수와 시작관련 프로그램 설정 지정파일</p>
</li>
<li><p>~/.bashrc :개인 사용자가 정의한 alias와 함수들이 있는 파일</p>
</li>
<li><p>~/.bash_profile : 개인 사용자가 정의한  alias와 함수 설정파일</p>
</li>
</ol>
<p>/etc/passwd</p>
<p>시스템에 등록된 각 사용자의 계정 정보를 저장, 사용자 ID, 그룹 ID, 홈 디렉토리, 로그인 셸 등의 정보를 포함. 사용자의 로그인 셸 정보는 각 사용자의 레코드 마지막 부분에 위치.</p>
<p>/etc/shells: 시스템에서 사용 가능한 셸의 목록을 포함. 사용자가 chsh 명령어를 사용하여 변경할 수 있는 유효한 셸을 나열.</p>
<p>/etc/bashrc: 시스템 전체의 기본 설정을 위한 bash 셸 스크립트 파일. 모든 사용자의 bash 셸 세션에 대한 글로벌 구성을 제공.</p>
<p>/etc/profile: 시스템 전체의 로그인 셸 세션을 위한 초기화 스크립트 파일. 모든 사용자의 로그인 셸 세션 시작 시 실행.</p>
<p>R : 복잡한 데이터 분석과 시각화를 위한 강력한 도구를 제공</p>
<p>Hadoop: 대규모 데이터 세트를 분산 처리하기 위한 프레임워크. 데이터 저장과 처리에 유용</p>
<p>NoSQL: 관계형 데이터베이스의 대안으로, 빅데이터와 실시간 웹 애플리케이션을 위한 다양한 데이터베이스 기술</p>
<p>Cassandra: 고가용성과 확장성을 제공하는 분산 NoSQL 데이터베이스 시스템</p>
<p>FTP 서버에 파일을 업로드하는 명령어 = put</p>
<p>FTP 서버에서 파일을 다운로드하는 명령어 = get</p>
<hr>
<p>telnet 옵션</p>
<ul>
<li>u : UDP 모드로 telnet을 실행</li>
<li>n : 호스트 이름을 숫자로 변환하지 않고, 주소로 처리</li>
<li>p : 원격 호스트이 포트를 지정</li>
<li>l : 로그인 할 때 사용 할 사용자 이름을 지정</li>
</ul>
<ol>
<li><p>.Xsession: 사용자가 로그인할 때 실행되는 스크립트로, 사용자가 세션을 시작할 때 실행되는 명령을 포함할 수 있습니다.</p>
</li>
<li><p>.Xsetup: 일반적으로 XDM(X Display Manager)과 관련된 설정 파일로, XDM을 사용하는 로그인 화면 설정에 사용됩니다.</p>
</li>
<li><p>.Xinitrc: 사용자가 startx 명령을 통해 X 윈도우 시스템을 시작할 때 실행되는 스크립트로, 사용자 정의 초기화 명령을 포함할 수 있습니다.</p>
</li>
<li><p>.Xauthority: X 서버에 대한 인증 정보를 저장하는 파일로, X 클라이언트가 X 서버에 접근할 수 있도록 하는 인증 키를 저장합니다.</p>
</li>
</ol>
<p>윈도 매니저 ： ｘ－윈도우 상에서 윈도의 배치와 표현을 담당하는 시스템 프로그램</p>
<p>디스플레이 매니저 ： ｘ－윈도우 구성 요소 중 사용자 로그인 및 세션 관리 수행 프로그램</p>
<p>ps명령 상태 코드</p>
<ul>
<li>R (Running): 프로세스가 현재 실행 중인 상태</li>
<li>S (Sleeping): 프로세스가 현재 실행 대기 중인 상태. 실행 대기 중이지만 사용자 입력이나 이벤트를 기다리고 있다. 대부분의 프로세스가 이 상태에 있다.</li>
<li>T (Stopped): 프로세스가 현재 중지된 상태. 보통은 SIGSTOP 시그널을 받아 중지된 상태이며, 실행을 일시 중지한 후에 다시 시작할 수 있다</li>
<li>Z (Zombie): 프로세스가 종료되었지만 부모 프로세스가 아직 종료 상태를 확인하지 않은 상태. 일반적으로 시스템 리소스를 소비하지 않으며, 부모 프로세스가 해당 종료 상태를 처리할 때까지 존재.</li>
</ul>
<p>ps : 현재 실행 중인 프로세스</p>
<p>bg : 중지된(background)작업을 다시 실행</p>
<p>jobs : 현재 셸에서 실행 중인 작업의 목록(백그라운드, 포그라운드 모두 표시)</p>
<p>exec : 셸 스크립트가 다른 프로세스로 대체</p>
<p>SIGTSTP - 20 : Terminal Stop Signal (POSIX)</p>
<p>SIGKILL - 9 : Kill(can&#39;t be caught or ignored) (POSIX)</p>
<p>SIGINT - 2 : Terminal Interrupt (ANSI)</p>
<p>SIGTERM - 15 : Termination (ANSI)</p>
<p>chsh</p>
<ul>
<li>l = list shells : 셸의 목록을 출력하여 사용자가 사용할 수 있는 셀의 종류를 확인</li>
<li>u = help : 명령어의 사용법과 가능한 옵션에 대한 간단한 설명 제공</li>
<li>s : 사용자의 기본 셸을 변경</li>
<li>c = comment : 변경된 셸에 대한 추가적인 설명을 제공</li>
</ul>
<p>/etc/fstab 은 파일 시스템 테이블을 나타내는 파일</p>
<p>/etc/mtab 파일은 현재 마운트된 파일 시스템에 관한 정보</p>
<p>/etc/mounts 파일은 파일 시스템이 실제로 마운트되어 있는지 여부와 관계없이 보여줍니다.</p>
<p>/proc/partitions 파일은 현재 시스템에 있는 파티션 정보를 제공</p>
<p>NFS (Network File System) : 네트워크를 통해 파일을 공유할 수 있게 해주는 시스템임. 리눅스나 유닉스 시스템끼리 파일 공유할 때 주로 사용함.</p>
<p>SAMBA : 윈도우 파일 공유 프로토콜인 SMB/CIFS를 구현한 거임. 윈도우와 리눅스/유닉스 시스템 간에 파일이나 프린터를 공유할 수 있게 해줌.</p>
<p>Gopher : 인터넷 초기에 사용되던 정보 검색 프로토콜임. 웹이 널리 퍼지기 전에 문서나 파일을 계층적으로 찾아볼 수 있게 해주는 시스템이었지만, 지금은 거의 안 쓰임.</p>
<p>FTP (File Transfer Protocol) : 파일을 컴퓨터와 컴퓨터 사이에 전송하기 위해 사용되는 프로토콜임. 웹 브라우저나 전용 클라이언트를 통해 파일 업로드, 다운로드 할 때 사용됨.</p>
<p>A클래스: 0.0.0.0 ~ 127.255.255.255</p>
<p>B클래스: 128.0.0.0 ~ 191.255.255.255</p>
<p>C클래스: 192.0.0.0 ~ 223.255.255.255</p>
<p>1계층 물리 계층 - bit</p>
<p>2계층 데이터 링크 계층 - frame</p>
<p>3계층 네트워크 계층 - packet</p>
<p>4계층 전송 계층 - segment</p>
<p>DISPLAY=원격지로 전송하기 위해 변경하는 변수</p>
<p>VISUAL = 사용자의 기본 텍스트 에디터를 나타내는 환경 변수</p>
<p>TERM = 터미널 유형을 나타내는 환경 변수</p>
<p>XTERM =  X 윈도우 시스템에서 사용되는 터미널 에뮬레이터의 종류를 나타내는 환경 변수</p>
<p>mount 와 umount
 마운트는 특정 디바이스를 특정 디렉터리처럼 사용하기 위해 장치와 디렉터리를 연결한
다.
 리눅스는 PnP 기능을 지원하지만 지원하는 하드웨어가 많지 않으므로 시스템 부팅후에
수동으로 마운트해서 사용을 하고 사용이 끝난 후에는 언마운트를 시킨다.
 파일 /etc/mtab 은 현재 마운트된 블록 시스템 정보를 표시한다.</p>
<p>eject
 이동식 보조기억장치등과 같은 미디어를 해제하고 장치를 제거하는 명령어이다.</p>
<p>fdisk
 새로운 파티션의 생성, 기존 파티션의 삭제, 파티션의 타입 결정 등의 작업을 수행할 수
있다.
 한 번에 한 디스크에 대해서만 작업을 수행한다.</p>
<p>mkfs
 리눅스 파일 시스템을 생성한다.
 fdisk로 하드디스크를 파티션을 나눈 후 해당 파티션에 맞는 파일 시스템을 생성한다.</p>
<p>mke2fs
 ext2, ext3, ext4 타입의 리눅스 파일 시스템을 생성하는 명령어이다.</p>
<p>fsck
 파일 시스템의 무결성을 점검하고 대화식으로 복구하는 명령어이다.
 디렉터리 /lost+found 는 fsck 에서 사용하는 디렉터리이다.</p>
<p>e2fsck
 ext2, ext3, ext4 타입의 리눅스 파일 시스템을 복구하는 명령어이다.</p>
<p>du
 Disk Usage의 약자로 디렉터리별로 디스크 사용량을 확인할 수 있다.</p>
<p>df
 시스템에 마운트된 하드 디스크의 남은 용량을 확인할 때 사용하는 명령어이다.
 기본적으로 1024 Byte 블록 단위로 출력한다</p>
<p> TCP/IP주소 설정 정보 확인: ifconfig, nslookup
 네트워크 경로 상태 확인: ping, traceroute
 네트워크 연결 상태 확인: netstat
 라우팅 테이블 확인: route
 NIC 상태 확인: ethtool, mii-tool, arp</p>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/6de5e1aa-9b49-49d9-8e70-88b33b611256/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/97050641-eb50-4aa8-88b4-a15a8977f8c2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/cba4a179-3940-4553-b33e-658865ac5482/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정보처리기사 핵심 개념 벼락치기!]]></title>
            <link>https://velog.io/@eleven_ill/%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EA%B8%B0%EC%82%AC-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90-%EB%B2%BC%EB%9D%BD%EC%B9%98%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EA%B8%B0%EC%82%AC-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90-%EB%B2%BC%EB%9D%BD%EC%B9%98%EA%B8%B0</guid>
            <pubDate>Tue, 05 Nov 2024 06:08:18 GMT</pubDate>
            <description><![CDATA[<p><strong>정처기를 준비하시는 많은 분들 아래 내용만 빠르게 암기하고 합격하세요!!</strong></p>
<p><strong>주요 암기 내용!!</strong></p>
<p>디자인패턴</p>
<p>서브넷구하기</p>
<p>블랙박스 테스트 기법</p>
<p>프로세스 스케줄링 구하기</p>
<p>페이지교체알고리즘 구하기</p>
<p>코드 커버리지</p>
<p>내부라우팅프로토콜</p>
<p>최단거리알고리즘 종류</p>
<p><strong>업캐스팅의 원칙</strong></p>
<p><strong>1.자식에 이름이 같은 메서드가 있으면 우선 작동한다.</strong></p>
<p><strong>2.자식에 super()가 있으면, 부모의 그것을 호출한다.</strong></p>
<p><strong>3.부모에 자식과 같은 메서드가 있으면, 자식을 호출한다.</strong></p>
<p>python set은 {}, list는 [] </p>
<p>차이점은 set은 중복 없고 순서 상관 없다.</p>
<pre><code>
select * from table;

insert into table(A,B,C) values(’A’,1,’2’); 

delete from table where 조건

update table set A=’1’,B=’a’ where ~ and ~</code></pre><p>select문 순서 : select,from,where,group by,having, order by</p>
<p>UML의 3요소 : 사물, 관계, 다이어그램</p>
<p>이상현상의 종류 : 삽입이상, 삭제이상, 수정이상</p>
<p>블랙박스 테스팅(명세기반) : 사용자 ‘요구사항’에 대한 명세를 기반 (특정 기능 test)</p>
<p>화이트박스 테스팅(구조기반) : SW내부’구조’에 따라 검사(논리적 경로를 test)</p>
<p>블랙/화이트 모두 동적 test이다.</p>
<p>테스트 수행 순서 : 단위T → 통합T → 시스템T → 인수T</p>
<p>비밀키 암호화 기법</p>
<p>DES : 1970년 대칭키 암호화, 64bit, Data Encryption Standard</p>
<p>AES : DES대신 새로운 기법, 128bit, Advanced Encryption Standard</p>
<p>파일구조 : 순차, 인덱스, 해싱</p>
<p>패킷 교환 방식 </p>
<p>연결형 : 가상회선       비연결형 : 데이터그램</p>
<p>GoF 디자인패턴 : 생성패턴, 구조패턴, 행위패턴</p>
<p>ARP : IP → MAC                 RARP : MAP → IP</p>
<p>IPv4 : 32bit , 10진수 표현, 2^32</p>
<p>IPv6 : 128bit, 16진수 표현, 2^128</p>
<table>
<thead>
<tr>
<th>접근통제정책</th>
<th>MAC</th>
<th>RBAC</th>
<th>DAC</th>
</tr>
</thead>
<tbody><tr>
<td>권한부여</td>
<td>시스템</td>
<td>중앙관리자</td>
<td>데이터소유자</td>
</tr>
<tr>
<td>접근결정</td>
<td>보안등급</td>
<td>역할(Role)</td>
<td>신분</td>
</tr>
</tbody></table>
<p>트리거 : DB에 특정 사건 발생시 ‘자동’으로 수행되는 저장프로시저</p>
<p>hadoop: 빅데이터를 쉽게 활용하도록 하는 분산파일시스템</p>
<p>공개키(비대칭키) 암호화 기법 : RSA, EIgama, ECC, DSS</p>
<p>비밀기(대칭키) 암호화 기법 : DES, AES, ARIA, SEED, IDEA</p>
<p>해시 : 임의의 길이의 메세지 입력으로 하여 고정된 길이의 출력 값을 변환하는 기법</p>
<p>해시함수 : 단방향 암호화 함수</p>
<p>정보보안 3요소 (CIA) : 무결성, 기밀성, 가용성</p>
<p>IDS(Intrusion Detection System) : 침입 탐지 시스템</p>
<p>IPS(Intrusion Prevention System) : 침입 방지 시스템</p>
<p>NAC(Network Access Control) : 네트워크 접근 제어</p>
<p>ESM(Enterprise Security Manage) : 통합 보안 관리</p>
<p>VPN(Virtual private Network) : 가상 사설 망</p>
<p>AAA(인증, 권한부여, 계정관리) 프레임 워크 : </p>
<p>인증(Authentication) , 권한부여(Authorization) , 계정(Accounting)</p>
<p>DBA : 데이터베이스 관리자</p>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/a585d13f-d5fb-4df3-a503-e82fc91ba786/image.png" alt=""></p>
<p>내부스키마 : 물리적 저장 장치 관점 (기계 관점) 물리적 구조</p>
<p>개념스키마 : 논리적 관점 (사용자 관점)</p>
<p>외부스키마 : 서브스키마이자 사용자가 사용하는 한 부분에서본 논리적 구조</p>
<p>슈퍼키 : 유일성은 만족, 최소성은 만족X</p>
<p>(후보키랑 기본키는 둘다 만족)</p>
<p>이행함수 종속 : A → B,  B → C 일때 A → C인 경우</p>
<p>트랜잭션 : DB내에서 수행되는 하나의 작업 처리를 위한 논리적 작업 단위</p>
<p>트랜잭션 종류 : 원자성, 일관성, 영속성, 격리성</p>
<p>회복기법 : REDO(재수행), UNDO(취소)</p>
<p>로킹(Locking) : 트랜잭션 병행 시 접근 못하게 하는 것</p>
<p>프로토콜 : 둘 이상 컴퓨터 사이 데이터 전송하도록 송.수신측에서 정한 통신 규칙</p>
<p>기본요소 : 구문, 의미, 타이밍</p>
<p>X.25 : 흐름 및 오류 제어 기능 제공, 패킷 교환망 접속 위한 인터페이스 프로토콜</p>
<p>형상관리 : SW개발 단계에 생성되는 모든 문서, 코드를 통침</p>
<p>종류 : 버전관리, 변경관리</p>
<p>CVS(동시 버전 시스템) : Concurrent Version System</p>
<p>SVN(Subversion) : CVS에서 2000년 콜랩이 개선</p>
<p>GIT : 지역 , 원격 저장소로 분리</p>
<p>와이어프레임 : 와이어로 설계된 정적이고 간단한 표현 상태</p>
<p>목업(MockUp): 와이어보다 더 실제와 유사하게 만든 실물 크기의 정적모형</p>
<p>UI Prototype : 시스템 개발시, 요구사항을 좀 더 구체화 하는 도구 </p>
<p>제작 단계 : 요구분석 → 프로토타입 작성 → 사용자 test → 수정 및 합의</p>
<p>소프트웨어 아키텍처 : SW전체 시스템의 전반적인 구조를 설계하는것</p>
<p>ISO/IEC 9126모델 : SW품질 특성과 평가를 위한 국제 표준</p>
<p>UI 설계 원칙 : 직관성, 유효성, 학습성, 유연성</p>
<p>미들웨어 : 서로 다른 프로토콜 환경에서 원만하게 연결하도록 돕는 도구</p>
<p>파레토의 법칙 : 2:8법칙으로 결과의 80프로가 전체원인의 20프로에서 일어나는 현상</p>
<p>코드 커버리지 : 소스코드의 테스트 수행정도를 표시</p>
<p>종류 : 구문, 조건, 결정, 변경/조건, 다중조건 커버리지</p>
<p>단위모듈 테스트(UnitTest) : 단위 기능을 구현하는 모듈 test</p>
<p>ex)화이트박스 테스트, 블랙박스 테스트</p>
<p>통합 테스트(Integration Test) : 서로 간 상호작용 오류 및 결함을 찾는 test</p>
<p>비점진적 통합방식(빅뱅) : 전체test</p>
<p>점진적 통합방식(상향식, 하향식) : 단계적 test</p>
<p>샌드위치 test : 상향식 + 하향식의 서로의 장점만 이용하는 방식의 test</p>
<p>회귀 시험 (Regression Test) : 새로운 변경사항이 기존의 ‘부작용’을 없게 test</p>
<p>유형 : Retest All, Selective, Priority</p>
<p>결함 : 1.에러 ,   2.결점, 결함, 버그,   3.실패(장애)</p>
<p>AJAX(Asynchronous Javascript And XML) 비동기 자바스크립트 그리고 xml</p>
<p>장점 : 웹페이지 속도 향상 </p>
<p>단점 : 보안 문제, 기록관리 x</p>
<p>HIPO : 기본 모델로 입력,처리,출력으로 구성되는 시스템 분석 기법</p>
<p>SW재공학 : 이미 개발 인정 받은 sw 전체나 부분을 ‘다시 새롭게 사용’</p>
<p>과정 : 분석 → 구성 → 역공학 → 이식</p>
<p>역공학 : sw개발과정이나 데이터 처리과정을 재발견 하거나 다시 만드는 작업</p>
<p>Agile애자일 방법론 : sw설계 변경에 ‘신속히’ 대응, 요구사항 수용</p>
<p>XP(eXtreme Programming) : 개발중 요구사항의 변동이 심한경우 적합한 방법론</p>
<p>핵심가치 : 소통, 단순성, 피드백, 용기, 존중</p>
<p>scrum : 반복적이고 점진적인 소규모 팀 중심의 sw 개발론</p>
<p>플랫폼 : 응용 sw + 하드웨어 + 시스템sw</p>
<p>미들웨어 : 운영체제와 소프트웨어 어플리케이션 사이에 위치</p>
<p>SWEBOK에 따른 요구사항 개발 프로세스</p>
<p>도출 → 분석 → 명세 → 확인</p>
<p>JAD(Joint Application Development) 결합 응용 설계 : 브레인스토밍 회의</p>
<p>SDLC(Software Development Life Cycle) : sw생명주기</p>
<p>객체지향 구성요소 : Class, Object, Message</p>
<p>객체지향 특징 : 캡슐화, 정보은닉, 추상화, 상속성, 다향성</p>
<p>프로세스 스케줄링 (*는 계산문제 예상)</p>
<p>선점형 기법 : RR(Round Robin), *SRT, MLQ, MLFQ</p>
<p>비선점형 기법 : *FCFS, *SJF, *HRN, 우선순위, 기한부</p>
<p>HRN 식 : (대기사간+실행시간)/실행시간 → 값이 높은게 우선순위 높은것. </p>
<p>cron표현식 : 분   시   일   월   요일</p>
<p>일요일:0 이고 토요일은 6으로 표시 , 안나온 값은 *로 표시</p>
<p>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
위에 해당하는 개념만 빠르게 보면 필기 시험 합격!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@GetMapping 과 @PostMapping]]></title>
            <link>https://velog.io/@eleven_ill/GetMapping-%EA%B3%BC-PostMapping</link>
            <guid>https://velog.io/@eleven_ill/GetMapping-%EA%B3%BC-PostMapping</guid>
            <pubDate>Tue, 05 Nov 2024 06:02:36 GMT</pubDate>
            <description><![CDATA[<p><strong><code>@GetMapping</code></strong>과 <strong><code>@PostMapping</code></strong>은 스프링 프레임워크에서 웹 애플리케이션의 컨트롤러에서 사용되는 어노테이션입니다. 이 두 어노테이션은 HTTP 요청 메서드(GET 및 POST)에 따라 해당 메서드가 어떤 URL 경로에서 실행되어야 하는지 지정하는 데 사용됩니다. 같은 컨트롤러 클래스에서 두 어노테이션을 모두 사용하는 이유와 그 차이점은 다음과 같습니다:</p>
<ol>
<li><p><strong>사용 이유</strong>:</p>
<ul>
<li><strong><code>@GetMapping</code></strong>: 이 어노테이션은 HTTP GET 요청을 처리하는 메서드에 사용됩니다. 주로 데이터를 조회하고 가져오는 데 사용됩니다. 예를 들어, 웹 페이지에서 데이터를 표시하거나 검색 결과를 요청하는 경우에 사용됩니다.</li>
<li><strong><code>@PostMapping</code></strong>: 이 어노테이션은 HTTP POST 요청을 처리하는 메서드에 사용됩니다. 주로 데이터를 생성하거나 업데이트하는 데 사용됩니다. 예를 들어, 사용자가 어떤 데이터를 제출하고 서버에 저장하거나 업데이트하는 경우에 사용됩니다.</li>
</ul>
</li>
<li><p><strong>차이점</strong>:</p>
<ul>
<li>HTTP 요청 메서드: 가장 큰 차이점은 요청 메서드입니다. <strong><code>@GetMapping</code></strong>은 GET 요청을 처리하고, <strong><code>@PostMapping</code></strong>은 POST 요청을 처리합니다. GET 요청은 데이터를 조회할 때 사용되며, POST 요청은 데이터를 생성 또는 업데이트할 때 사용됩니다.</li>
<li>요청 매개변수: <strong><code>@GetMapping</code></strong>은 주로 URL 경로 변수와 쿼리 매개변수를 사용하여 데이터를 전달합니다. 반면에 <strong><code>@PostMapping</code></strong>은 주로 HTTP 요청 본문(body)을 통해 데이터를 전달합니다. 이로 인해 데이터 전달 방식에 차이가 있습니다.</li>
<li>안전성: <strong><code>@GetMapping</code></strong>은 주로 데이터 조회 및 검색과 같은 안전한(read-only) 작업에 사용됩니다. 데이터를 읽기만 하고 변경하지 않는 작업입니다. <strong><code>@PostMapping</code></strong>은 데이터를 변경하거나 생성하는 작업에 사용되므로 보안 및 데이터 무결성에 더 신경을 써야 합니다.</li>
<li>캐싱: 일반적으로 GET 요청은 캐싱될 수 있고, 동일한 요청에 대한 응답이 캐시에서 제공될 수 있습니다. 반면에 POST 요청은 일반적으로 캐싱되지 않습니다.</li>
</ul>
</li>
</ol>
<p>따라서 컨트롤러 클래스에서 <strong><code>@GetMapping</code></strong>과 <strong><code>@PostMapping</code></strong>을 모두 사용하는 경우, 해당 컨트롤러에서 데이터를 조회 및 수정하는 두 가지 다른 작업을 처리할 수 있습니다. 이를 통해 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@Transactional 과 @Rollback의 이해]]></title>
            <link>https://velog.io/@eleven_ill/Transactional-%EA%B3%BC-Rollback%EC%9D%98-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@eleven_ill/Transactional-%EA%B3%BC-Rollback%EC%9D%98-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Tue, 05 Nov 2024 06:01:32 GMT</pubDate>
            <description><![CDATA[<p><strong><code>@Transactional</code></strong>과 <strong><code>@Rollback</code></strong>은 주로 테스트 환경에서 사용되는 어노테이션으로, 데이터베이스 연동 테스트에서 트랜잭션 관리와 롤백을 다루는 데에 사용됩니다.</p>
<h2 id="정의와-사용법">정의와 사용법</h2>
<ol>
<li><p><strong>@Transactional 어노테이션</strong>:</p>
<ul>
<li><strong><code>@Transactional</code></strong> 어노테이션은 테스트 메소드 내에서 실행되는 모든 작업을 하나의 트랜잭션으로 묶어줍니다.</li>
<li>이를 통해 테스트 메소드가 실행되는 동안 데이터베이스에 변경 사항을 적용하고, 테스트가 끝날 때 트랜잭션을 롤백하여 원래 상태로 되돌릴 수 있습니다.</li>
<li>따라서 테스트가 실패하더라도 데이터베이스는 변하지 않습니다.</li>
</ul>
</li>
<li><p><strong>@Rollback 어노테이션</strong>:</p>
<ul>
<li><p><strong><code>@Rollback</code></strong> 어노테이션은 <strong><code>@Transactional</code></strong>과 함께 사용될 때, 해당 테스트 메소드의 실행 후에 트랜잭션을 롤백하도록 지정합니다.</p>
</li>
<li><p><strong><code>@Rollback</code></strong> 어노테이션을 사용하지 않으면 테스트 메소드의 작업이 실제로 데이터베이스에 적용될 수 있습니다.</p>
</li>
<li><p><strong><code>@Rollback(true)</code></strong>로 설정하면 테스트 메소드의 작업이 트랜잭션을 통해 실행되며, 테스트 종료 후 데이터베이스는 롤백됩니다.</p>
</li>
<li><p><strong><code>@Rollback(false)</code></strong>로 설정하면 테스트 메소드의 작업이 트랜잭션을 통해 실행되고, 테스트 종료 후 데이터베이스는 롤백되지 않습니다.</p>
<h2 id="독립적인-사용과-같이-사용하는-경우">독립적인 사용과 같이 사용하는 경우</h2>
</li>
<li><p><em><code>@Transactional</code>*</em>과 <strong><code>@Rollback</code></strong> 어노테이션은 같이 사용할 수도 있지만, 반드시 같이 사용해야 하는 것은 아닙니다. 각 어노테이션은 다음과 같이 독립적으로 사용될 수 있습니다.</p>
</li>
</ul>
<ol>
<li><p><strong><code>@Transactional</code>만 사용하는 경우</strong>:</p>
<ul>
<li>테스트 메소드 내에서 데이터베이스 작업을 수행하고, 트랜잭션으로 묶어서 실행하며, 테스트가 종료될 때 해당 트랜잭션을 롤백합니다.</li>
<li>이 경우에는 <strong><code>@Rollback</code></strong> 어노테이션을 명시적으로 사용하지 않아도 기본적으로 테스트 종료 후 롤백됩니다.</li>
</ul>
</li>
<li><p><strong><code>@Rollback</code>만 사용하는 경우</strong>:</p>
<ul>
<li><strong><code>@Transactional</code></strong> 없이 <strong><code>@Rollback</code></strong> 어노테이션만 사용하면, 테스트 메소드 내에서 데이터베이스 작업을 수행하고, 테스트가 종료될 때 해당 트랜잭션을 롤백합니다.</li>
<li>테스트 메소드 내에서 직접 트랜잭션을 사용하는 것이 아니기 때문에 일부 상황에서는 제한적일 수 있습니다.</li>
</ul>
</li>
<li><p><strong>두 어노테이션 모두 사용하는 경우</strong>:</p>
<ul>
<li><strong><code>@Transactional</code></strong>과 <strong><code>@Rollback</code></strong> 어노테이션을 모두 사용하면, 테스트 메소드 내에서 데이터베이스 작업을 트랜잭션으로 묶고, 테스트가 종료될 때 트랜잭션을 롤백합니다.</li>
<li><strong><code>@Rollback</code></strong> 어노테이션을 사용하여 <strong><code>@Transactional</code></strong>의 롤백 동작을 명시적으로 설정할 수 있습니다.</li>
</ul>
<p>어노테이션을 사용하는 방식은 테스트 목적과 상황에 따라 다를 수 있습니다. 일반적으로는 <strong><code>@Transactional</code></strong>을 주로 사용하며, 데이터베이스 작업을 수행하고 테스트 종료 후 롤백하여 테스트 전 상태를 유지하는 데 활용됩니다. <strong><code>@Rollback</code></strong>은 추가적인 롤백 제어가 필요한 경우에 사용될 수 있습니다.</p>
<h2 id="요약">요약</h2>
</li>
</ol>
<p> <strong><code>@Transactional</code></strong> 어노테이션은 트랜잭션을 시작하고 종료하며, <strong><code>@Rollback</code></strong> 어노테이션은 해당 트랜잭션의 롤백 동작을 지정합니다. 두 어노테이션을 어떻게 조합하느냐에 따라 테스트가 데이터베이스에 어떤 영향을 미치는지를 조절할 수 있습니다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Fetch vs Axios]]></title>
            <link>https://velog.io/@eleven_ill/Fetch-vs-Axios</link>
            <guid>https://velog.io/@eleven_ill/Fetch-vs-Axios</guid>
            <pubDate>Tue, 05 Nov 2024 05:54:47 GMT</pubDate>
            <description><![CDATA[<p><code>fetch</code>와 <code>axios</code>는 둘 다 JavaScript에서 HTTP 요청을 보낼 때 사용되는 라이브러리입니다. 그러나 둘 사이에는 여러 차이점이 있습니다. 여기서는 각자의 장단점과 예제 코드를 비교해 보겠습니다.</p>
<h3 id="1-fetch-api">1. <code>fetch</code> API</h3>
<p><code>fetch</code>는 기본적으로 브라우저에 내장된 함수입니다. 별도의 설치가 필요 없으며, 프로미스 기반의 HTTP 요청을 보낼 수 있습니다.</p>
<h3 id="장점">장점:</h3>
<ul>
<li><strong>내장 API</strong>: 별도 설치가 필요 없음.</li>
<li><strong>표준화</strong>: 브라우저에 표준적으로 내장된 API.</li>
</ul>
<h3 id="단점">단점:</h3>
<ul>
<li><strong>자동 오류 처리 부족</strong>: <code>fetch</code>는 네트워크 오류에만 오류 처리를 해주고, HTTP 상태 코드가 400이나 500일 경우 자동으로 오류를 던지지 않음. 따라서 명시적으로 처리해야 함.</li>
<li><strong>JSON 자동 변환 없음</strong>: JSON 응답을 수동으로 <code>.json()</code> 메서드를 사용해 파싱해야 함.</li>
<li><strong>타임아웃 처리 없음</strong>: <code>fetch</code>에는 타임아웃 기능이 내장되어 있지 않아 별도로 구현해야 함.</li>
</ul>
<h3 id="예제-코드">예제 코드:</h3>
<pre><code class="language-jsx">fetch(&#39;https://api.example.com/data&#39;)
  .then(response =&gt; {
    if (!response.ok) {
      throw new Error(&#39;Network response was not ok&#39;);
    }
    return response.json(); // 수동으로 JSON 파싱
  })
  .then(data =&gt; console.log(data))
  .catch(error =&gt; console.error(&#39;Fetch error:&#39;, error));</code></pre>
<h3 id="2-axios-라이브러리">2. <code>axios</code> 라이브러리</h3>
<p><code>axios</code>는 별도의 설치가 필요한 외부 라이브러리입니다. (Node.js나 브라우저에서 사용 가능)</p>
<h3 id="장점-1">장점:</h3>
<ul>
<li><strong>자동 JSON 변환</strong>: 응답 데이터를 자동으로 JSON으로 변환.</li>
<li><strong>간단한 오류 처리</strong>: HTTP 상태 코드가 200이 아닐 경우 자동으로 오류를 던짐.</li>
<li><strong>타임아웃 지원</strong>: 타임아웃 기능을 기본 제공.</li>
<li><strong>요청 취소 가능</strong>: 요청을 취소할 수 있는 기능을 제공.</li>
<li><strong>Interceptors</strong>: 요청 및 응답에 대한 중간 처리가 가능함.</li>
</ul>
<h3 id="단점-1">단점:</h3>
<ul>
<li><strong>추가 설치 필요</strong>: <code>npm</code>이나 <code>CDN</code>을 통해 별도로 설치해야 함.</li>
<li><strong>무거운 의존성</strong>: 작은 프로젝트에서 사용하기에 다소 무거울 수 있음.</li>
</ul>
<h3 id="설치">설치:</h3>
<pre><code class="language-bash">npm install axios</code></pre>
<h3 id="예제-코드-1">예제 코드:</h3>
<pre><code class="language-jsx">const axios = require(&#39;axios&#39;); // Node.js 환경에서의 예시

axios.get(&#39;https://api.example.com/data&#39;)
  .then(response =&gt; console.log(response.data)) // 자동으로 JSON 변환
  .catch(error =&gt; console.error(&#39;Axios error:&#39;, error));</code></pre>
<h3 id="주요-차이점-요약">주요 차이점 요약:</h3>
<ol>
<li><strong>내장 여부</strong>: <code>fetch</code>는 브라우저에 내장, <code>axios</code>는 외부 라이브러리.</li>
<li><strong>JSON 파싱</strong>: <code>fetch</code>는 수동, <code>axios</code>는 자동.</li>
<li><strong>오류 처리</strong>: <code>fetch</code>는 네트워크 오류만 잡고, HTTP 오류는 수동 처리. <code>axios</code>는 자동으로 모든 오류를 처리.</li>
<li><strong>타임아웃</strong>: <code>axios</code>는 타임아웃을 기본 제공, <code>fetch</code>는 수동으로 구현해야 함.</li>
</ol>
<p>두 라이브러리는 각자의 장단점이 있으니, 프로젝트의 필요에 따라 선택하면 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기식 python 함수 처리, 핸들러]]></title>
            <link>https://velog.io/@eleven_ill/%EB%B9%84%EB%8F%99%EA%B8%B0%EC%8B%9D-python-%ED%95%A8%EC%88%98-%EC%B2%98%EB%A6%AC-%ED%95%B8%EB%93%A4%EB%9F%AC</link>
            <guid>https://velog.io/@eleven_ill/%EB%B9%84%EB%8F%99%EA%B8%B0%EC%8B%9D-python-%ED%95%A8%EC%88%98-%EC%B2%98%EB%A6%AC-%ED%95%B8%EB%93%A4%EB%9F%AC</guid>
            <pubDate>Tue, 05 Nov 2024 05:53:38 GMT</pubDate>
            <description><![CDATA[<p>비동기 프로그래밍은 특정 작업을 수행하는 동안 다른 작업을 동시에 처리할 수 있는 방식입니다. Python에서 <code>asyncio</code> 모듈은 비동기 프로그래밍을 지원하여, 비동기 함수들을 작성하고 실행할 수 있게 합니다. 이 방식의 주요 목적은 <strong>효율적인 I/O 작업 처리</strong>입니다.</p>
<h3 id="비동기-프로그래밍의-이유">비동기 프로그래밍의 이유</h3>
<ol>
<li><strong>I/O 작업 중 대기 시간 줄이기</strong>:<ul>
<li>네트워크 요청, 파일 읽기/쓰기, 데이터베이스 쿼리 등 많은 I/O 작업은 대기 시간이 발생합니다. 예를 들어, 파일을 읽는 동안 CPU는 그 파일이 디스크에서 읽혀지기를 기다려야 합니다.</li>
<li>비동기 프로그래밍은 이런 대기 시간 동안 다른 작업을 수행할 수 있게 해줍니다. 즉, I/O 작업이 완료되기를 기다리는 동안 다른 함수가 실행될 수 있어, 자원을 더 효율적으로 사용할 수 있습니다.</li>
</ul>
</li>
<li><strong>효율적인 자원 사용</strong>:<ul>
<li>비동기 방식에서는 CPU를 더 효율적으로 사용하며, 특히 많은 I/O 작업을 처리하는 서버 애플리케이션에서 성능을 크게 향상시킬 수 있습니다. 이는 여러 작업이 대기 상태일 때 다른 작업을 처리할 수 있기 때문입니다.</li>
</ul>
</li>
</ol>
<h3 id="비동기-프로그래밍의-장단점">비동기 프로그래밍의 장단점</h3>
<h3 id="장점">장점</h3>
<ol>
<li><strong>동시성</strong>:<ul>
<li>여러 작업을 동시에 처리하는 것처럼 보이게 합니다. 실제로는 하나의 스레드에서 실행되지만, 비동기 방식으로 여러 I/O 작업을 병렬로 처리할 수 있습니다.</li>
<li>비동기 함수들은 작업 간의 전환이 효율적이어서, 많은 클라이언트의 요청을 동시에 처리해야 하는 웹 서버와 같은 애플리케이션에서 유리합니다.</li>
</ul>
</li>
<li><strong>스레드/프로세스 오버헤드 감소</strong>:<ul>
<li>전통적인 멀티스레딩 또는 멀티프로세싱 방식과 달리, 비동기 프로그래밍은 추가적인 스레드 또는 프로세스를 생성하지 않아도 됩니다. 이로 인해 스레드/프로세스 간의 문맥 전환 비용이 줄어들고, 더 적은 자원으로 높은 동시성을 달성할 수 있습니다.</li>
</ul>
</li>
<li><strong>효율적인 I/O 처리</strong>:<ul>
<li>비동기 방식으로 I/O를 처리하면, CPU가 I/O 대기 시간 동안 유휴 상태에 머물지 않고 다른 작업을 수행할 수 있습니다.</li>
</ul>
</li>
</ol>
<h3 id="단점">단점</h3>
<ol>
<li><strong>복잡성 증가</strong>:<ul>
<li>비동기 코드는 동기 코드보다 이해하고 디버그하기 어렵습니다. 작업이 비동기적으로 발생하고, 그 작업들이 여러 곳에서 실행될 수 있기 때문에 코드의 흐름을 추적하기 복잡해질 수 있습니다.</li>
</ul>
</li>
<li><strong>데드락 및 레이스 컨디션</strong>:<ul>
<li>비동기 코드를 잘못 작성하면, 예상치 못한 데드락(작업이 서로 끝나기를 기다리며 영원히 대기하는 상황)이나 레이스 컨디션(두 개 이상의 작업이 동시에 실행되며 서로 간섭하여 예기치 않은 결과를 초래하는 상황)이 발생할 수 있습니다.</li>
</ul>
</li>
<li><strong>비동기 라이브러리 의존</strong>:<ul>
<li>비동기 프로그래밍을 사용할 때는 비동기 방식으로 작동하는 라이브러리를 사용해야 합니다. 모든 라이브러리가 비동기 방식을 지원하는 것은 아니므로, 호환성을 고려해야 합니다.</li>
</ul>
</li>
</ol>
<h3 id="async와-await-구문-설명"><code>async</code>와 <code>await</code> 구문 설명</h3>
<ul>
<li><p><strong><code>async</code> 키워드</strong>:</p>
<ul>
<li><p>이 키워드는 함수 정의 앞에 붙여서 해당 함수가 비동기로 작동할 것임을 명시합니다. <code>async</code>로 정의된 함수는 <strong>코루틴</strong>이 됩니다.</p>
</li>
<li><p>코루틴은 일종의 함수지만, 일반적인 함수와 달리 실행이 중단될 수 있고, 중단된 지점부터 다시 실행할 수 있습니다.</p>
<pre><code class="language-python">python코드 복사
async def my_coroutine():
  # 비동기 작업을 수행하는 코드
  pass
</code></pre>
</li>
</ul>
</li>
<li><p><strong><code>await</code> 키워드</strong>:</p>
<ul>
<li><p><code>await</code>는 비동기 함수(또는 코루틴)를 호출할 때 사용합니다. 이 키워드는 비동기 작업이 완료될 때까지 현재 함수의 실행을 일시적으로 중단하고, 비동기 작업이 완료되면 실행을 재개합니다.</p>
</li>
<li><p><code>await</code>는 <strong>비동기 함수 내에서만</strong> 사용할 수 있습니다.</p>
<pre><code class="language-python">python코드 복사
async def my_coroutine():
  result = await some_async_function()  # 비동기 함수의 완료를 기다림
  print(result)
</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="간단한-예제">간단한 예제</h3>
<pre><code class="language-python">python코드 복사
import asyncio

async def fetch_data():
    print(&quot;Start fetching data...&quot;)
    await asyncio.sleep(2)  # 2초간 대기 (I/O 작업을 시뮬레이션)
    print(&quot;Data fetched!&quot;)
    return {&quot;data&quot;: &quot;sample&quot;}

async def main():
    print(&quot;Before fetching data&quot;)
    data = await fetch_data()
    print(&quot;After fetching data:&quot;, data)

asyncio.run(main())
</code></pre>
<h3 id="코드-설명">코드 설명</h3>
<ol>
<li><strong><code>fetch_data</code> 함수</strong>:<ul>
<li><code>async</code>로 정의된 비동기 함수입니다. 이 함수는 2초간 대기(<code>await asyncio.sleep(2)</code>)한 후 데이터를 반환합니다.</li>
<li><code>await asyncio.sleep(2)</code>는 2초간 대기하는 동안 다른 작업이 실행될 수 있도록 CPU 제어를 양보합니다.</li>
</ul>
</li>
<li><strong><code>main</code> 함수</strong>:<ul>
<li><code>main</code> 함수에서도 비동기 함수인 <code>fetch_data</code>를 호출하기 위해 <code>await</code>를 사용합니다.</li>
<li><code>asyncio.run(main())</code>는 이벤트 루프를 실행하고, <code>main</code> 함수가 종료될 때까지 대기합니다.</li>
</ul>
</li>
</ol>
<h3 id="결론">결론</h3>
<p>비동기 프로그래밍은 특히 I/O 중심 작업에서 효율성을 극대화할 수 있습니다. <code>asyncio</code> 모듈과 <code>async</code>, <code>await</code> 키워드를 사용하면 Python에서 이러한 비동기 작업을 쉽게 구현할 수 있습니다. 하지만, 비동기 코드는 복잡성이 증가할 수 있으므로 필요에 따라 신중하게 사용하는 것이 중요합니다.</p>
<h1 id="비동기-함수와-핸들러의-역할"><strong>비동기 함수와 핸들러의 역할</strong></h1>
<p>비동기 프로그래밍에서는 작업이 실행되기를 기다리기보다는, 작업이 완료될 때까지 다른 작업을 계속 실행할 수 있습니다. 이렇게 하면 프로그램의 효율성이 크게 향상됩니다.</p>
<h3 id="1-비동기-함수-async-function">1. <strong>비동기 함수 (async function)</strong></h3>
<ul>
<li><code>async def</code>로 정의된 함수는 비동기 함수입니다.</li>
<li>이 함수는 호출 시 작업을 바로 실행하지 않고, 비동기적으로 실행할 수 있도록 준비만 해둡니다.</li>
<li>비동기 함수는 <code>await</code> 키워드로 다른 비동기 작업을 기다립니다.</li>
</ul>
<pre><code class="language-python">python코드 복사
async def my_async_function():
    await some_other_async_function()
</code></pre>
<h3 id="2-핸들러-handler">2. <strong>핸들러 (Handler)</strong></h3>
<ul>
<li>비동기 함수의 결과를 처리하는 데 사용되는 함수입니다.</li>
<li>예를 들어, 비동기 작업이 완료되면 호출되는 콜백 함수가 핸들러 역할을 할 수 있습니다.</li>
<li>핸들러는 비동기 작업의 성공, 실패, 또는 특정 이벤트가 발생했을 때 실행됩니다.</li>
</ul>
<pre><code class="language-python">python코드 복사
async def process_data():
    data = await fetch_data()
    handle_data(data)

def handle_data(data):
    # 데이터를 처리하는 코드
</code></pre>
<p>위 코드에서 <code>handle_data</code> 함수는 <code>process_data</code> 비동기 함수 내에서 비동기 작업이 완료된 후 호출되는 핸들러의 역할을 합니다.</p>
<h3 id="비동기-핸들러의-실사용-예">비동기 핸들러의 실사용 예</h3>
<p>비동기 프로그래밍에서 핸들러는 다음과 같은 상황에서 주로 사용됩니다:</p>
<ul>
<li><strong>I/O 작업 (파일 읽기/쓰기, 네트워크 요청 등)</strong>: 작업이 완료되면 결과를 처리하거나 오류를 처리하기 위해 핸들러가 호출됩니다.</li>
<li><strong>이벤트 기반 시스템</strong>: 특정 이벤트가 발생했을 때, 해당 이벤트에 대한 처리를 수행하기 위해 핸들러가 사용됩니다.</li>
</ul>
<h3 id="python에서의-예제">Python에서의 예제</h3>
<pre><code class="language-python">python코드 복사
import asyncio

async def download_file(url):
    print(f&quot;Downloading from {url}&quot;)
    await asyncio.sleep(2)  # 파일 다운로드 시뮬레이션
    return &quot;file_content&quot;

async def save_file(content):
    print(&quot;Saving file...&quot;)
    await asyncio.sleep(1)  # 파일 저장 시뮬레이션
    print(f&quot;File saved with content: {content}&quot;)

async def main():
    file_content = await download_file(&quot;http://example.com&quot;)
    await save_file(file_content)

asyncio.run(main())
</code></pre>
<p>이 예제에서 <code>download_file</code>과 <code>save_file</code>은 비동기 함수이며, <code>main</code> 함수는 비동기 작업이 완료될 때 이를 처리하는 핸들러 역할을 합니다. 이 방식으로 비동기 작업의 결과를 처리할 수 있습니다.</p>
<p>핸들러는 주로 비동기 작업의 결과를 처리하거나, 에러가 발생했을 때 이를 처리하기 위해 사용되며, 비동기 프로그래밍의 핵심 구성 요소입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[유닉스 커맨드 명령어]]></title>
            <link>https://velog.io/@eleven_ill/%EC%9C%A0%EB%8B%89%EC%8A%A4-%EC%BB%A4%EB%A7%A8%EB%93%9C-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@eleven_ill/%EC%9C%A0%EB%8B%89%EC%8A%A4-%EC%BB%A4%EB%A7%A8%EB%93%9C-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Tue, 05 Nov 2024 05:50:44 GMT</pubDate>
            <description><![CDATA[<h1 id="vim의-4-가지-사용-모드"><strong>vim의 4 가지 사용 모드</strong></h1>
<p>vim에는 4가지 사용 모드가 있습니다:</p>
<ul>
<li>일반 모드</li>
<li>입력 모드</li>
<li>비주얼 모드</li>
<li>명령 모드</li>
</ul>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/19e5a5b7-159a-499c-8311-d127fe99f3f6/image.png" alt=""></p>
<p>아래와 같은 단축키로 모드 전환 가능</p>
<p><img src="https://velog.velcdn.com/images/eleven_ill/post/10f1e8f6-f240-42ea-a67d-816d12778d67/image.png" alt=""></p>
<h1 id="단축키-정리"><strong>단축키 정리</strong></h1>
<ul>
<li>텍스트 입력: 입력 모드(i) → 텍스트 입력</li>
<li>텍스트 한 줄 복사: 일반 모드 → 복사하고 싶은 줄에 커서 위치 → yy</li>
<li>텍스트 한 줄 잘라내기: 일반 모드 → 잘라내고 싶은 줄에 커서 위치 → dd</li>
<li>특정 영역 복사: 비주얼 모드(V는 줄 단위, v는 글자 단위) → 복사하고 싶은 영역 커서로 설정 → y</li>
<li>특정 영역 잘라내기: 비주얼 모드(V는 줄 단위, v는 글자 단위) → 잘라내고 싶은 영역 커서로 설정 → d</li>
<li>텍스트 붙여넣기: 일반 모드 → 붙여넣고 싶은 위치에 커서 위치 → p</li>
<li>파일 저장: 명령 모드(:) → w + enter</li>
<li>파일 저장 + vim 종료: 명령 모드(:) → wq + enter</li>
<li>vim 종료 (내용 저장되지 않음): 명령 모드(:) → q! + enter</li>
</ul>
<p>cat : 파일 내용 출력</p>
<p>less : 한페이지씩 파일 내용 보기</p>
<p>head : 파일의 처음 10줄 보기 (default 값이 10임)</p>
<p>tail : 파일의 마지막 10줄 보기 (default 값이 10임)</p>
<p>처음 15줄만 보여주기  : head -n 15 test.txt</p>
<p>마지막 15줄만 보여주기  : tail -n 15 test.txt</p>
<p><strong>파일과 디렉토리 옮기기 &amp; 이름 변경하기</strong></p>
<p><strong>mv path1 path2</strong> </p>
<p><strong>파일 디렉토리 복사 붙여놓기</strong></p>
<p><strong>cp path1 path2</strong> </p>
<p>path2가 이미 존재하면 path1을 path2로 이동하고,</p>
<p>path2가 존재하지 않으면 path1을 path2로 이름 변경하게 된다.</p>
<p>주의점: 같은 이름의 파일이 있으면 내용을 덮어쓰게된다.</p>
<p>충돌이 있으면 사용자에게 주의를 주는 옵션인 i옵션을 사용해야한다.</p>
<p>ex) mv -i test1.txt test2.txt</p>
<p>라고 명령어 사용하면 overwrite? y/n 나오고 이 상황에서 y,n선택</p>
<p>ex) cp -r Test Test_copy ← -r옵션을 사용해야 폴더 속에 있는 모든 것 복사</p>
<h1 id="rm-remove"><strong><code>rm</code> (remove)</strong></h1>
<pre><code class="language-bash">
rm [-rif] PATH1 PATH2 ...</code></pre>
<p><code>r</code> 옵션: 디렉토리를 삭제할 때는 꼭 <code>r</code> 옵션을 써야 합니다.</p>
<p><code>i</code> 옵션: 삭제할 때 각 파일을 정말 지울 것인지 물어봅니다.</p>
<p><code>f</code> 옵션: 지울 것인지 절대 확인하지 않고 바로 지웁니다.</p>
<p>ex) rm -rf /path/to/dir  ← 묻지 않고 강제로 삭제</p>
<h1 id="apt">apt</h1>
<p>우분투에서 외부 프로그램을 설치하고 관리하는데 사용하는 툴</p>
<p>사용하기 전에 <strong>apt update</strong> 무조건 실행</p>
<p>관리자 권한 일시적으로 갖는 명령어 : <strong>sudo</strong></p>
<p><strong>sudo apt update 관리자 권한으로 실행</strong></p>
<p>프로그램 설치 : <strong>sudo apt install</strong> mc  ← mc는 gui처럼 폴더 볼 수 있는 프로그램</p>
<p> (mc치면 시작, f10으로 종료)</p>
<p>프로그램 제거 : <strong>sudo apt remove mc</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSV 파일 string데이터 원래 데이터타입으로 변경]]></title>
            <link>https://velog.io/@eleven_ill/CSV-%ED%8C%8C%EC%9D%BC-string%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9B%90%EB%9E%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@eleven_ill/CSV-%ED%8C%8C%EC%9D%BC-string%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9B%90%EB%9E%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Tue, 05 Nov 2024 05:29:09 GMT</pubDate>
            <description><![CDATA[<h3 id="1-데이터베이스에-다시-삽입하여-데이터-타입-복원">1. 데이터베이스에 다시 삽입하여 데이터 타입 복원</h3>
<p>가장 확실한 방법은 CSV 파일의 데이터를 다시 데이터베이스에 삽입하여 데이터베이스의 원래 스키마를 사용해 데이터 타입을 복원하는 것입니다.</p>
<h3 id="step-1-csv-파일-가져오기">Step 1: CSV 파일 가져오기</h3>
<p>먼저 CSV 파일을 데이터베이스의 임시 테이블에 가져옵니다. 임시 테이블의 모든 컬럼을 문자열 타입으로 설정합니다.</p>
<pre><code class="language-sql">sql코드 복사
CREATE TABLE temp_table (
    col1 VARCHAR(255),
    col2 VARCHAR(255),
    col3 VARCHAR(255),
    ...
);
</code></pre>
<h3 id="step-2-csv-파일-로드">Step 2: CSV 파일 로드</h3>
<p>CSV 파일을 임시 테이블에 로드합니다. 예를 들어 MySQL에서는 다음과 같이 할 수 있습니다.</p>
<pre><code class="language-sql">sql코드 복사
LOAD DATA INFILE &#39;/path/to/your/file.csv&#39;
INTO TABLE temp_table
FIELDS TERMINATED BY &#39;,&#39;
ENCLOSED BY &#39;&quot;&#39;
LINES TERMINATED BY &#39;\n&#39;
IGNORE 1 ROWS;
</code></pre>
<h3 id="step-3-데이터-타입-변환하여-원래-테이블에-삽입">Step 3: 데이터 타입 변환하여 원래 테이블에 삽입</h3>
<p>원래 테이블로 데이터를 삽입하면서 필요한 데이터 타입으로 변환합니다.</p>
<pre><code class="language-sql">sql코드 복사
INSERT INTO original_table (col1, col2, col3, ...)
SELECT
    CAST(col1 AS INT),
    CAST(col2 AS DECIMAL(10, 2)),
    col3,  -- 이미 문자열인 경우
    ...
FROM temp_table;
</code></pre>
<h3 id="2-python과-pandas를-사용하여-데이터-타입-복원">2. Python과 Pandas를 사용하여 데이터 타입 복원</h3>
<p>CSV 파일을 Pandas 데이터프레임으로 불러와 각 컬럼의 데이터 타입을 변환할 수 있습니다.</p>
<pre><code class="language-python">python코드 복사
import pandas as pd

# CSV 파일 불러오기
df = pd.read_csv(&#39;/path/to/your/file.csv&#39;)

# 각 컬럼의 데이터 타입 변환
df[&#39;col1&#39;] = df[&#39;col1&#39;].astype(int)
df[&#39;col2&#39;] = df[&#39;col2&#39;].astype(float)
df[&#39;col3&#39;] = df[&#39;col3&#39;].astype(str)

# 변환된 데이터프레임을 새로운 CSV 파일로 저장
df.to_csv(&#39;/path/to/your/new_file.csv&#39;, index=False)
</code></pre>
<h3 id="3-dbeaver에서-데이터-타입-변경">3. DBeaver에서 데이터 타입 변경</h3>
<p>DBeaver와 같은 도구에서는 CSV 파일을 불러온 후 직접 데이터 타입을 변경할 수 있습니다.</p>
<h3 id="step-1-csv-파일-불러오기">Step 1: CSV 파일 불러오기</h3>
<p>DBeaver에서 CSV 파일을 임포트합니다.</p>
<h3 id="step-2-데이터-타입-변경">Step 2: 데이터 타입 변경</h3>
<ol>
<li>임포트된 데이터가 있는 테이블을 선택합니다.</li>
<li>테이블 구조를 편집 모드로 엽니다.</li>
<li>각 컬럼의 데이터 타입을 적절하게 변경합니다.</li>
</ol>
<h3 id="4-excel에서-데이터-타입-변경">4. Excel에서 데이터 타입 변경</h3>
<p>Excel을 사용하여 데이터 타입을 변환한 후 CSV로 저장할 수도 있습니다.</p>
<h3 id="step-1-csv-파일-열기">Step 1: CSV 파일 열기</h3>
<p>Excel에서 CSV 파일을 엽니다.</p>
<h3 id="step-2-데이터-타입-변경-1">Step 2: 데이터 타입 변경</h3>
<p>각 셀 또는 컬럼의 데이터 타입을 변경합니다. 예를 들어, 숫자 데이터는 &quot;숫자&quot; 형식으로 변경합니다.</p>
<h3 id="step-3-csv-파일로-저장">Step 3: CSV 파일로 저장</h3>
<p>다시 CSV 파일로 저장합니다.</p>
<h3 id="결론">결론</h3>
<p>위의 방법 중 하나를 선택하여 CSV 파일의 데이터를 원래 데이터 타입으로 복원할 수 있습니다. 데이터베이스에 다시 삽입하여 변환하는 방법이 가장 확실하지만, Python을 사용하거나 DBeaver, Excel 등의 도구를 이용하여 변환하는 방법도 상황에 따라 유용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ ODBC로 DB 연결하기]]></title>
            <link>https://velog.io/@eleven_ill/ODBC%EB%A1%9C-DB-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/ODBC%EB%A1%9C-DB-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 05 Nov 2024 05:27:02 GMT</pubDate>
            <description><![CDATA[<h1 id="odbc와-nodejs를-이용하여-tibero-db에-접속하기">odbc와 node.js를 이용하여 tibero DB에 접속하기</h1>
<ul>
<li><strong>Node.js와 npm 설치</strong>: Node.js와 npm이 설치되어 있는지 확인합니다. 설치되어 있지 않다면, <a href="https://nodejs.org/">Node.js 공식 웹사이트</a>에서 다운로드하여 설치합니다.</li>
<li><strong>설치 확인</strong>:</li>
</ul>
<pre><code class="language-bash">
node -v
npm -v
</code></pre>
<ul>
<li><p><strong>프로젝트 초기화</strong>:</p>
<pre><code class="language-bash">
  mkdir tibero-connection
  cd tibero-connection
  npm init -y
</code></pre>
</li>
</ul>
<h3 id="odbc-모듈-설치"><code>odbc</code> 모듈 설치</h3>
<pre><code class="language-bash">
npm install odbc
</code></pre>
<h3 id="odbcinstini-파일-설정">odbcinst.ini 파일 설정</h3>
<p><strong>[root@ctl-svr tibero-connection]# cat /etc/odbcinst.ini</strong>    실행하면 아래와 같음</p>
<p>Example driver definitions</p>
<p>Driver from the postgresql-odbc package</p>
<p>Setup from the unixODBC package</p>
<pre><code class="language-bash">[Tibero6]
Description     = Tibero6 ODBC driver
Driver          = /root/tibero6/client/lib/libtbodbc.so
Setup           = /root/tibero6/client/lib/libtbodbc.so
FileUsage       = 1</code></pre>
<h3 id="odbcini-파일-설정">odbc.ini 파일 설정</h3>
<p><strong>[root@ctl-svr tibero-connection]# cat /etc/odbc.ini</strong>  실행하면 아래와 같음
[ODBC]
Trace=1
TraceFile=/home/python/.odbc.trace</p>
<pre><code class="language-bash">[tibero]
#Driver=/root/tibero6/client/lib/libtbodbc.so
Driver=Tibero6
Description=Tibero6 ODBC Datasource
Trace=Yes
Server=X.X.X.X
Port=port_number
User=user_name
Password=user_pwd
Database=DB_name</code></pre>
<p><strong>index.js 코드는 아래와 같다</strong></p>
<pre><code>const odbc = require(&#39;odbc&#39;);

async function connectToTibero() {
    try {
        const connection = await odbc.connect(&#39;DSN=tibero&#39;);
        console.log(&#39;Connected to Tibero DB&#39;);

        // 데이터베이스 작업 수행
        const result = await connection.query(&#39;SELECT * FROM your_table_name&#39;);
        console.log(result);

        // 연결 종료
        await connection.close();
        console.log(&#39;Connection closed&#39;);
    } catch (err) {
        console.error(&#39;Error connecting to Tibero DB:&#39;, err);
    }
}

connectToTibero();
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[연결한 DB정보 .csv파일로 추출하고 다른 타켓 시스템으로 옮기기]]></title>
            <link>https://velog.io/@eleven_ill/%EC%97%B0%EA%B2%B0%ED%95%9C-DB%EC%A0%95%EB%B3%B4-.csv%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EC%B6%94%EC%B6%9C%ED%95%98%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%83%80%EC%BC%93-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9C%BC%EB%A1%9C-%EC%98%AE%EA%B8%B0%EA%B8%B0</link>
            <guid>https://velog.io/@eleven_ill/%EC%97%B0%EA%B2%B0%ED%95%9C-DB%EC%A0%95%EB%B3%B4-.csv%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EC%B6%94%EC%B6%9C%ED%95%98%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%83%80%EC%BC%93-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9C%BC%EB%A1%9C-%EC%98%AE%EA%B8%B0%EA%B8%B0</guid>
            <pubDate>Tue, 05 Nov 2024 05:21:54 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스의 데이터를 추출해서 다른 IP 주소로 옮기기 위해서는, 데이터를 파일로 추출한 후, 그 파일을 타겟 IP 주소의 시스템으로 전송하고, 전송된 파일을 타겟 시스템의 데이터베이스에 로드하는 과정을 거쳐야 합니다.</p>
<p>아래 단계에 따라 진행할 수 있습니다</p>
<p><strong>전제 조건 : node.js, npm, odbc 설치가 되어있고 odbcinst.ini와 odbc.ini가 작성되어야한다.</strong></p>
<p>자세한건 ODBC로 DB 연결 하는 방법 참고!</p>
<h3 id="1-데이터-추출-export">1. 데이터 추출 (Export)</h3>
<p>현재 시스템에서 데이터를 CSV 파일로 추출합니다. 예를 들어, Node.js를 사용하여 데이터를 CSV 파일로 추출할 수 있습니다.</p>
<h3 id="nodejs-코드-csv-파일로-데이터-추출">Node.js 코드 (CSV 파일로 데이터 추출)</h3>
<p>먼저, <code>csv-writer</code> 패키지를 설치합니다.</p>
<pre><code class="language-bash">
npm install csv-writer
</code></pre>
<ol>
<li><strong>우선 아래 코드처럼 db_read.js 라는 파일을 만들어서 테이블의 정보를 연결해서 조회한다.</strong></li>
</ol>
<pre><code class="language-jsx">
const odbc = require(&#39;odbc&#39;);

async function connectToTibero() {
    try {
        const connection = await odbc.connect(&#39;DSN=tibero&#39;);
        console.log(&#39;Connected to Tibero DB&#39;);

        // 데이터베이스 작업 수행 (테이블 이름만 수정하여 실행)
        const result = await connection.query(&#39;SELECT * FROM your_table&#39;);
        console.log(result);

        // 연결 종료
        await connection.close();
        console.log(&#39;Connection closed&#39;);
    } catch (err) {
        console.error(&#39;Error connecting to Tibero DB:&#39;, err);
    }
}

connectToTibero();
</code></pre>
<p><strong>node db_read.js</strong>   로 실행 하면 테이블을 조회하고 빈 테이블이면 칼럼정보만, 데이터값이 있으면 데이터 값을 보여주고 이후 칼럼 정보까지 출력해준다.</p>
<ol>
<li><strong>1번에서 db_read.js로 정상적인 db를 확인했다면, csv_output.js 파일을 아래와 같이 작성한다.</strong></li>
</ol>
<pre><code class="language-jsx">
const odbc = require(&#39;odbc&#39;);
const createCsvWriter = require(&#39;csv-writer&#39;).createObjectCsvWriter;

async function connectAndExportToCSV() {
    try {
        const connection = await odbc.connect(&#39;DSN=tibero&#39;);
        console.log(&#39;Connected to Tibero DB&#39;);

        // 데이터베이스 작업 수행 (your_table만 테이블 명으로 수정하고 실행)
        const result = await connection.query(&#39;SELECT * FROM your_table&#39;);

        // CSV 파일 작성 (path : &#39;table명.csv&#39; 로 수정하고 실행)
        const csvWriter = createCsvWriter({
            path: &#39;output.csv&#39;,
            header: Object.keys(result[0]).map(key =&gt; ({id: key, title: key}))
        });

        await csvWriter.writeRecords(result);
        console.log(&#39;Data has been written to CSV file&#39;);

        // 연결 종료
        await connection.close();
        console.log(&#39;Connection closed&#39;);
    } catch (err) {
        console.error(&#39;Error connecting to Tibero DB:&#39;, err);
    }
}

connectAndExportToCSV();
</code></pre>
<p>다음으로, node csv_output.js 로 실행하면 해당 테이블의 데이터를 CSV 파일로 추출합니다.</p>
<p>이 스크립트는 데이터베이스에서 데이터를 쿼리하고, 결과를 <code>output.csv</code> 파일로 저장합니다.</p>
<h3 id="2-파일-전송-transfer">2. 파일 전송 (Transfer)</h3>
<p>파일을 현재 시스템 ip(192.168.x.x)에서 타겟 시스템 ip(192.168.y.y)로 전송합니다.</p>
<h3 id="scp-secure-copy-명령어-사용">SCP (Secure Copy) 명령어 사용</h3>
<pre><code class="language-bash">
scp output.csv user@192.168.y.y:/path/to/destination/
</code></pre>
<p>여기서 <code>user</code>는 타겟 시스템의 사용자 이름이고, <code>/path/to/destination/</code>는 파일을 저장할 경로입니다. 본인은 scp TABLE_NAME.csv <a href="mailto:root@192.168.X.X">root@192.168.X.X</a>:/root/csv/ 로 수정</p>
<p><strong>위와 같이 scp 명령어를 통하여 현재 ip에서 원하는 타겟ip로 파일을 전송하고, 해당 ip에 접속하여</strong></p>
<p><strong>/root/csv/에 존재하는 csv파일을 다운로드 한 이후 DBeaver을 통해 연결한 csv데이터베이스를 조회하여 편하게 사용 가능하다.</strong></p>
]]></description>
        </item>
    </channel>
</rss>