<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>code.log</title>
        <link>https://velog.io/</link>
        <description>일상</description>
        <lastBuildDate>Tue, 22 Apr 2025 07:23:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>code.log</title>
            <url>https://velog.velcdn.com/images/seungho7-1/profile/722028e8-34ca-4449-ba99-16fa45e827de/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. code.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/seungho7-1" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[ Spring MVC에서 Form 객체를 템플릿(Thymeleaf)으로 전달하는 방법]]></title>
            <link>https://velog.io/@seungho7-1/Spring-MVC%EC%97%90%EC%84%9C-Form-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%ED%85%9C%ED%94%8C%EB%A6%BFThymeleaf%EC%9C%BC%EB%A1%9C-%EC%A0%84%EB%8B%AC%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@seungho7-1/Spring-MVC%EC%97%90%EC%84%9C-Form-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%ED%85%9C%ED%94%8C%EB%A6%BFThymeleaf%EC%9C%BC%EB%A1%9C-%EC%A0%84%EB%8B%AC%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 22 Apr 2025 07:23:29 GMT</pubDate>
            <description><![CDATA[<h2 id="1-자동-바인딩-방식">1. 자동 바인딩 방식</h2>
<pre><code class="language-java">@GetMapping(&quot;/create&quot;)
public String create(QuestionForm questionForm) {
    return &quot;question_form&quot;;
}

// 내부적으로는 아래와 같은 코드와 동일하게 작동함:
model.addAttribute(&quot;questionForm&quot;, new QuestionForm());</code></pre>
<h2 id="2-수동-바인딩-방식-model-이용">2. 수동 바인딩 방식 (Model 이용)</h2>
<pre><code class="language-java">@GetMapping(&quot;/create&quot;)
public String create(Model model) {
    model.addAttribute(&quot;questionForm&quot;, new QuestionForm());
    return &quot;question_form&quot;;
}

</code></pre>
<h2 id="3-명시적-modelattribute-방식">3. 명시적 @ModelAttribute 방식</h2>
<pre><code class="language-java">@GetMapping(&quot;/create&quot;)
public String create(@ModelAttribute(&quot;questionForm&quot;) QuestionForm form) {
    return &quot;question_form&quot;;
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[유효성 검사(@Valid)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%ACValid</link>
            <guid>https://velog.io/@seungho7-1/%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%ACValid</guid>
            <pubDate>Wed, 02 Apr 2025 18:22:53 GMT</pubDate>
            <description><![CDATA[<h2 id="도메인-객체-vs-dto-에-대한-유효성-검사">도메인 객체 vs DTO 에 대한 유효성 검사</h2>
<h3 id="-같은-곳에-유효성-검사를-추가하면-코드-중복이-발생한다">= 같은 곳에 유효성 검사를 추가하면 코드 중복이 발생한다.</h3>
<ul>
<li><p>도메인 지식 같은 경우 -&gt; Domain(Entity)에 유효성 검사를 해야한다.</p>
</li>
<li><p>도메인 지식과 무관하게 데이터 그 자체가 유효한가에 대한 검사 -&gt; DTO에서 해야한다.</p>
<pre><code class="language-java">@Getter
@Setter
@Entity
public class Food {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Integer id;// 고유 번호

 @Column(length = 50)
 @Size(max = 50)
 private String foodname; // 식품명

 @Column(length = 30)
 @Size(max = 30)
 private String kind; // 종류

 private List&lt;String&gt; createDate;//날짜

 private String storageArea; // 구역


</code></pre>
</li>
</ul>
<pre><code>private LocalDateTime modifyDate; // 최종 수정 날짜

@ManyToOne// 작성자와의 관계 설정
private SiteUser siteuser;

private String imagePath; //이미지 경로</code></pre><p>}</p>
<p> ```</p>
<ul>
<li><p>@Size를 추가하여 유효성 검사를 추가했다.</p>
<pre><code class="language-java">@Getter
@Setter
@Entity
public class FoodFormDto {
 @NotEmpty(message=&quot;식품 이름은 필수 항목입니다.&quot;)
 @NotNull
 private String foodName;

 @NotEmpty(message=&quot;식품 종류 선택은 필수 항목입니다.&quot;)
 @NotNull
 private String kind;

 @NotEmpty(message=&quot;유통기한은 필수 항목입니다.&quot;)
 @NotNull
 private List&lt;String&gt; createDate;//날짜

 @NotEmpty(message=&quot;영역은 필수 항목입니다.&quot;)
 @NotNull
 private String storageArea;
</code></pre>
</li>
</ul>
<ul>
<li>입력 폼에 대한 @NotEmpty @NotNull을 이용하여 유효성 검사를 추가했다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot - DTO]]></title>
            <link>https://velog.io/@seungho7-1/SpringBoot-DTO</link>
            <guid>https://velog.io/@seungho7-1/SpringBoot-DTO</guid>
            <pubDate>Tue, 18 Mar 2025 20:43:41 GMT</pubDate>
            <description><![CDATA[<h1 id="dto">DTO</h1>
<h2 id="--data-transfer-object란-의미로-폼에서-전달받은-데이터를-객체로-변환하는것">- Data Transfer Object란 의미로 폼에서 전달받은 데이터를 객체로 변환하는것.</h2>
<ul>
<li>dto로 받은 데이터는 최종적으로 데이터베이스로 저장.</li>
</ul>
<h3 id="1-데이터를-form을-통해-post-요청으로-데이터를-요청">1. 데이터를 form을 통해 Post 요청으로 데이터를 요청.</h3>
<ul>
<li>폼 데이터를 전송 받아 DTO 객체에 담아야한다. -&gt; post 요청</li>
<li>폼 데이터를  DTO에 담기 -&gt; 컨트롤러에 매개 변수로 담는다.</li>
<li>폼과 DTO 필드를 연결하자 -&gt; 타임리프를 통해 mapping</li>
<li>DTO를 데이터베이스에 저장하자 -&gt; DTO를 엔티티로 변환하자.</li>
<li>repository로 엔티티를  db에 저장하자 -&gt; repository.save(Entity);</li>
</ul>
<pre><code class="language-html">// foodcreate_form.html

&lt;form class=&quot;container&quot; action=&quot;/api/food&quot; method=&quot;post&quot;&gt;
 &lt;div class=&quot;mb-3&quot;&gt;
            &lt;label for=&quot;foodName&quot; class=&quot;form-label&quot;&gt;식품명&lt;/label&gt;
            &lt;input type=&quot;text&quot; name=&quot;foodName&quot; id=&quot;foodName&quot; class=&quot;form-control&quot; placeholder=&quot;ex) 버터 치킨 카레&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;mb-3&quot;&gt;
            &lt;label for=&quot;createDate&quot; class=&quot;form-label&quot;&gt;유통 기한&lt;/label&gt;
            &lt;input type=&quot;text&quot; name=&quot;createDate&quot; id=&quot;createDate&quot; class=&quot;form-control&quot; placeholder=&quot;ex) 25/01/01&quot;&gt;
&lt;/div&gt;
&lt;/form&gt;
</code></pre>
<pre><code class="language-java">  DTO

public class FoodFormDto{

private String foodName;
private String createDate;

// 전송 받은 이름과 날짜를 저장하는 생성자 추가
public foodFormDto(String foodName,String createDate){ 
this.foodName = foodName;
this.createDate = createDate;
}
// dto를 entity로 변환
public Food toEntity(){
return new food(null,foodName,createDate);
}</code></pre>
<pre><code class="language-java">@Controller
public class foodcontroller(FoodFormDto foodFormDto){
@Gemapping(&quot;/api/food&quot;)
public String create(FoodFormDto foodFormDto){
Food food = foodFormDto.toEntity();
this.foodrepository.save(food);

}</code></pre>
<pre><code class="language-java">@Entity
public class Food{
@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;// 고유 번호

    @Column(length = 50)
    private String foodname; // 식품명

    private String createDate; // 제조일자
}

public Food(String foodname,String createDate){
this.foodname = foodname;
this.createDate = createDate;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[식품 유통기한 리스트]]></title>
            <link>https://velog.io/@seungho7-1/%EC%8B%9D%ED%92%88-%EC%9C%A0%ED%86%B5%EA%B8%B0%ED%95%9C-%EC%B2%B4%ED%81%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B81</link>
            <guid>https://velog.io/@seungho7-1/%EC%8B%9D%ED%92%88-%EC%9C%A0%ED%86%B5%EA%B8%B0%ED%95%9C-%EC%B2%B4%ED%81%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B81</guid>
            <pubDate>Mon, 27 Jan 2025 22:22:05 GMT</pubDate>
            <description><![CDATA[<h2 id="일하면서-짜증나서-만든-식품-유통기한-체크리스트를-만들기로-했다">일하면서 짜증나서 만든 식품 유통기한 체크리스트를 만들기로 했다.</h2>
<h3 id="1-개요">1. 개요</h3>
<p>본 문서는 Spring Boot 3 기반의 유통기한 기록, 문의사항, 보충 리스트 관리 웹/모바일 반응형 웹사이트 구축에 대한 설계 과정, MVC 패턴 적용, 요구사항 정의한다.</p>
<h3 id="2-시스템-설계">2. 시스템 설계</h3>
<h4 id="21-아키텍처">2.1 아키텍처</h4>
<ul>
<li>프론트엔드: 반응형 디자인 (BootStrap)</li>
<li>백엔드: Spring Boot 3 (RESTful API), Spring Data JPA (데이터베이스 연동), Thymeleaf (서버 사이드 렌더링)</li>
<li>데이터베이스: MySQL 또는 H2 (개발 환경)</li>
<li>웹 스토리지: HTML5 Web Storage (localStorage 또는 sessionStorage)<h4 id="22-mvc-패턴">2.2 MVC 패턴</h4>
</li>
<li>Model: 데이터베이스 엔티티 (Entity) 및 데이터 처리 로직 (Service)</li>
<li>View: Thymeleaf 템플릿 (웹 페이지)</li>
<li>Controller: RESTful API 엔드포인트, 웹 페이지 요청 처리<h4 id="23-주요-기능">2.3 주요 기능</h4>
</li>
<li>유통기한 기록: 제품별 유통기한 등록, 수정, 삭제, 조회</li>
<li>문의사항 관리: 사용자 문의 등록, 답변, 조회</li>
<li>보충 리스트 관리: 유통기한 기반 보충 필요 제품 목록 생성, 보충 수량 기록, 웹 스토리지 연동</li>
</ul>
<h3 id="3-요구사항-정의">3. 요구사항 정의</h3>
<h4 id="31-기능-요구사항">3.1 기능 요구사항</h4>
<h3 id="1-식품-리스트-관리">&lt;1&gt; 식품 리스트 관리</h3>
<ul>
<li>제품 정보 (제품명, 유통기한, 종류) 등록/수정/삭제</li>
<li>제품 정보 검색 기능</li>
<li>페이징 기능</li>
<li>유통기한 임박/만료 제품 목록 조회
&lt; 변경 UI &gt;</li>
<li>카드로 제품들을 정리</li>
</ul>
<h3 id="2-보충-리스트">&lt;2&gt; 보충 리스트</h3>
<ul>
<li>보충 리스트 관리</li>
<li>현장에서 보충 수량 입력으로 웹 스토리지 저장</li>
<li>보충 완료 목록 조회</li>
<li>보충 이력 조회</li>
<li>리스트 검색 기능<h3 id="3-문의-사항">&lt;3&gt; 문의 사항</h3>
</li>
<li>문의사항 관리</li>
<li>사용자 문의 등록 (제품, 문의 내용)</li>
<li>관리자 답변 등록</li>
<li>문의 목록 조회 (사용자, 관리자)</li>
<li>문의 검색 기능 (제품, 내용)</li>
</ul>
<h4 id="32-비기능-요구사항">3.2 비기능 요구사항</h4>
<ul>
<li>반응형 디자인: 다양한 기기 (PC, 태블릿, 모바일) 지원</li>
<li>성능: 빠른 응답 속도, 대용량 데이터 처리</li>
<li>보안: 사용자 인증/인가, 데이터 암호화</li>
<li>사용성: 직관적인 UI/UX, 쉬운 사용법</li>
<li>확장성: 새로운 기능 추가 용이</li>
<li>유지보수성: 코드 가독성, 유지보수 용이</li>
</ul>
<h3 id="4-개발-과정">4. 개발 과정</h3>
<ul>
<li>요구사항 분석 및 설계: 기능 요구사항, 비기능 요구사항 정의, 시스템 아키텍처 설계</li>
<li>데이터베이스 설계: ERD 작성, 테이블 설계</li>
<li>백엔드 개발: Spring Boot 3, Spring Data JPA, RESTful API 개발</li>
<li>프론트엔드 개발: BootStrap -&gt; 반응형 디자인 적용</li>
<li>웹 스토리지 연동: 보충 리스트 데이터 웹 스토리지 저장/관리</li>
<li>테스트: 단위 테스트, 통합 테스트, 시스템 테스트</li>
<li>배포: 서버 배포, 운영 환경 설정</li>
<li>유지보수: 버그 수정, 기능 개선, 성능 최적화</li>
</ul>
<h3 id="5-기술-스택">5. 기술 스택</h3>
<ul>
<li>Spring Boot 3: 백엔드 프레임워크</li>
<li>Data JPA: 데이터베이스 연동</li>
<li>Thymeleaf: 서버 사이드 렌더링</li>
<li>Bootstrap: 반응형 디자인 프레임워크</li>
<li>MySQL/H2: 데이터베이스</li>
<li>HTML5 Web Storage: 웹 스토리지</li>
</ul>
<h3 id="6-문서화">6. 문서화</h3>
<ul>
<li>요구사항 정의서</li>
<li>시스템 설계서</li>
<li>데이터베이스 설계서</li>
<li>API 명세서</li>
<li>테스트 계획서</li>
<li>사용자 매뉴얼</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 컨테이너와 스프링 빈]]></title>
            <link>https://velog.io/@seungho7-1/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88</link>
            <guid>https://velog.io/@seungho7-1/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88</guid>
            <pubDate>Mon, 21 Oct 2024 19:18:39 GMT</pubDate>
            <description><![CDATA[<h2 id="스프링-컨테이너와-스프링-빈">스프링 컨테이너와 스프링 빈</h2>
<h3 id="스프링-컨테이너-생성">스프링 컨테이너 생성</h3>
<pre><code class="language-java">ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);</code></pre>
<ul>
<li>ApplicationContext -&gt; 스프링 컨테이너이자 인터페이스</li>
<li>스프링 컨테이너 xml기반,Annotation을 기반으로 자바 설정 클래스로 만들 수 있다.</li>
</ul>
<h3 id="스프링-컨테이너의-생성-과정">스프링 컨테이너의 생성 과정</h3>
<ol>
<li>스프링 컨테이너 생성 </li>
</ol>
<ul>
<li>스프링 컨테이너에 (key : 빈이름(메소드명),value : 빈 객체(메소드 반환명 impl)</li>
<li>구성 정보 = AppConfig.class</li>
<li>이러한 구성 정보를 지정하고 활용한다.</li>
</ul>
<ol start="2">
<li>스프링 빈 등록</li>
</ol>
<ul>
<li>빈 이름은 메서드 이름 사용.</li>
<li>빈 이름 직접 부여 가능<pre><code class="language-java">@Test
@Bean(name:&#39;sprintHi&#39;)
public ~~</code></pre>
</li>
</ul>
<p>3.스프링 빈 의존관계 설정(DI)</p>
<ul>
<li>메소드의 반환값을 의존하는 메서드로 입력.<pre><code class="language-java">@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
</code></pre>
</li>
</ul>
<p>@Bean
public MemberRepository memberRepository(){
return new MemberMeberRepository();
}</p>
<pre><code>
### 컨테이너에 등록된 모든 빈 조회
-&gt; 스프링 컨테이너에 등록한 빈들이 잘 등록 되었는가?
1. 내부 bean + 등록한 bean 출력
2. 내부 bean만 출력

### 스프링 빈 조회 방법
1. ac.getBean(빈이름,타입)
2. ac.getBean(타입)
3. 예외발생시(NoSuchBeanDefinitionException) 예외를 사용하여 조회

### 스프링 빈 조회 - 동일한 타입이 둘 이상일때
- 같은 타입의 스프링 빈일때 오류 발생 -&gt; 빈이름 저장하여 조회
- ac.getBeansOfType() -&gt; 모든 빈 조회 가능</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Sort(합병 정렬)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Sort%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Sort%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Sun, 13 Oct 2024 11:36:04 GMT</pubDate>
            <description><![CDATA[<h2 id="merge-sort">Merge Sort</h2>
<h3 id="정의-분할정복-방식을-사용해-데이터를-분할하고-분할한-집합을-합치는-알고리즘이다">정의: 분할정복 방식을 사용해 데이터를 분할하고 분할한 집합을 합치는 알고리즘이다.</h3>
<ul>
<li>시간 복잡도는 O(nlogn)</li>
<li><blockquote>
<p>배열의 크기를 n이라 할때, 분할 할때 마다 배열의 크기가 n/2씩 감소. 
이때 분할하는데 걸리는 시간은 O(log n)</p>
</blockquote>
</li>
<li><blockquote>
<p>정복(합병)할때 마다 두 배열을 비교하면서 작은 요소부터 차례로 결과 배열에 추가.
이 과정에서 최대 (n)개의 요소를 비교하게 되므로, 두 개의 배열을 합치는 데 걸리는 시간은 O(n)</p>
</blockquote>
</li>
<li>대량의 데이터 정렬에 주로 사용.</li>
</ul>
<pre><code class="language-java">public class sort {
    public static void merge(int A[], int low, int mid, int high) {
        //정렬할게요.
        int B[] = new int[high + 1];
        int h = low; //임시 배열 B의 low.
        int i = low; //배열 A의 low
        int j = mid + 1; // 배열 A의 mid +1
        int k;

        while (i &lt;= mid &amp;&amp; j &lt;= high) {
            if (A[i] &lt; A[j]) {
                B[h] = A[i]; //작은 놈이 임시 배열 low 지수에 저장.
                i++; // 왼쪽 배열 포인터 증가
            } else{
                B[h] = A[j];
                j++;// 오른쪽 배열 포인터 증가
            }
            h++; //임시배열도 저장할 포인터를 1만큼 증가.
        }

        // 비교할게 없다면?
        if (i &gt; mid) { // 오른쪽 배열을 싹다 대입.
            for (k = j; k &lt;= high; k++) {
                B[h] = A[k];
                h++;
            }
        }else { // 왼쪽 배열을 싹다 임시배열 B에 대입.
            for (k = i; k &lt;= mid; k++) {
                B[h] = A[k];
                h++;
            }
        }

        /*while (i &lt;= mid) {
            B[h] = A[i];
            i++;
            h++;
        }
        while (j &lt;= high) {
            B[h] = A[j];
            j++;
            h++;
        }

         */

        for (k = low; k&lt;=high; k++) {
            A[k] = B[k];
        }
    }

    public static void printArray(int A[]) {
        for (int i = 0; i &lt; A.length; i++) {
            System.out.print(A[i] + &quot; &quot;);
        }
    }

    public static void mergeSort(int A[], int low, int high) { //합병할게요
        if (low &lt; high) {
            int mid = (low+high) /2;
            mergeSort(A,low,mid);
            mergeSort(A,mid+1,high);
            merge(A,low,mid,high);
        }
    }

    public static void main(String[] args) {
        int A[] = {91, 82, 13, 85, 68, 70, 98, 24};
        System.out.println(&quot;정렬전&quot;);
        printArray(A);
        System.out.println(&quot;정렬후&quot;);
        mergeSort(A,0,A.length-1);
        printArray(A);
    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Sort (Quick Sort)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Sort-Quick-Sort</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Sort-Quick-Sort</guid>
            <pubDate>Sat, 12 Oct 2024 16:20:35 GMT</pubDate>
            <description><![CDATA[<h2 id="quick-sort">Quick Sort</h2>
<h3 id="정의--분할정복-알고리즘으로-부분적으로-나누어가면서-정렬하는-방법">정의 : 분할정복 알고리즘으로 부분적으로 나누어가면서 정렬하는 방법.</h3>
<ul>
<li><p>시간 복잡도
최악: O(n^2)
평균: O(n*logn)</p>
</li>
<li><p>java에서 Arrays.sort()로 사용한다.</p>
</li>
</ul>
<h3 id="quick-sort-실행-방식">Quick Sort 실행 방식</h3>
<ol>
<li><p>배열을 두 부분으로 나눈다.
i) 배열 내 기준 요소보다 작으면 앞부분 배열에 위치, 크면 뒷부분 배열에 위치한다.</p>
</li>
<li><p>각 분할된 부분을 재귀적으로 정렬한다.</p>
</li>
</ol>
<pre><code class="language-java">package javastudy;

public class quickSort {
  public static void qs(int a[], int low, int high) {
    if (low &lt; high) {
      int s = partition(a, low, high); // 기준 pivot
      qs(a, low, s - 1); // 왼쪽 배열
      qs(a, s + 1, high); // 오른쪽 배열
    }
  }

  public static int partition(int a[], int low, int high) {
    int pivot = a[low]; // 피벗을 배열의 첫 번째 요소로 설정
    int i = low + 1;
    int j = high;

    while (i &lt;= j) {
      while (i &lt;= high &amp;&amp; a[i] &lt;= pivot) {
        i++;
      }
      while (j &gt;= low &amp;&amp; a[j] &gt; pivot) {
        j--;
      }
      if (i &lt; j) { // i가 j보다 작을 때만 교환
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
      }
    }
    // 피벗을 올바른 위치에 배치
    a[low] = a[j];
    a[j] = pivot;

    return j; // 피벗의 최종 위치 반환
  }

  public static void printArray(int a[]) {
    for (int num : a) {
      System.out.print(num + &quot; &quot;);
    }
    System.out.println(); // 배열 출력 후 줄바꿈
  }

  public static void main(String[] args) {
    int a[] = {8, 5, 6, 2, 4};
    printArray(a);
    qs(a, 0, a.length - 1); // 배열의 크기를 사용하여 인덱스 설정
    printArray(a);
  }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Sort(Insertion Sort)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-SortInsertion-Sort</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-SortInsertion-Sort</guid>
            <pubDate>Sat, 12 Oct 2024 15:59:55 GMT</pubDate>
            <description><![CDATA[<h2 id="insertion-sort">Insertion Sort</h2>
<h3 id="정의--자신의-위치를-찾아-삽입하는-정렬-알고리즘">정의 : 자신의 위치를 찾아 삽입하는 정렬 알고리즘.</h3>
<ul>
<li>정렬된 부분 (A[0]), 정렬 되지 않은 부분 (A[1] ... A[n-1])으로 구분하여 정렬.</li>
<li>시간복잡도 : O(n^2)</li>
</ul>
<pre><code class="language-java">package javastudy;

public class insertSort {
  public static void is(int a[]) {
    int n = a.length;
    for (int i = 1; i &lt; n; i++) {
      int insertionKey = a[i]; // 삽입할 현재 요소
      int j = i - 1;

      while (j &gt;= 0 &amp;&amp; a[j] &gt; insertionKey) {
        a[j+1] = a[j]; // 한칸 뒤로
        j = j-1; // 왼쪽 index로 이동
      }
      a[j+1] = insertionKey; // 현재 요소 삽입
    }
  }

  public static void printArray(int a[]) {
    for (int num : a) {
      System.out.print(num+ &quot; &quot;);
    }
  }

  public static void main(String[] args) {
    int A[] = {8, 5, 6, 2, 4};
    System.out.println(&quot;정렬 전&quot;);
    printArray(A);
    System.out.println(&quot;정렬 후&quot;);
    is(A);
    printArray(A);
  }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - sort (Selection Sort)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-sort-Selection-Sort</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-sort-Selection-Sort</guid>
            <pubDate>Sat, 12 Oct 2024 15:50:02 GMT</pubDate>
            <description><![CDATA[<h2 id="selection-sort">Selection Sort</h2>
<h3 id="정의--전체-배열에서-가장-작은-요소를-찾고-그-요소를-첫번째-요소와-교환하는-정렬">정의 : 전체 배열에서 가장 작은 요소를 찾고, 그 요소를 첫번째 요소와 교환하는 정렬.</h3>
<ul>
<li>시간 복잡도 : O(n^2)</li>
<li></li>
</ul>
<pre><code class="language-java">package javastudy;

public class selectionSort {
  public static void ss(int a[]) {
    int n = a.length;


    for (int i = 0; i &lt; n - 1; i++) {
      int min = i;
      for (int j = i+1; j &lt; n; j++) {
        if (a[min] &gt; a[j]) {
          min = j;
        }
      }
        if (min != i) {
          int tmp = a[i];
          a[i] = a[min];
          a[min] = tmp;
        }

    }
  }

  public static void printArray(int a[]) {
    for (int num : a) {
      System.out.print(num+&quot; &quot;);
    }
  }

  public static void main(String[] args) {
    int A[] = {8, 5, 6, 2, 4};
    System.out.println(&quot;정렬 전&quot;);
    printArray(A);
    System.out.println(&quot;정렬 후&quot;);
    ss(A);
    printArray(A);

  }

}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - sort (Bubble Sort)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-sort-Bubble-Sort</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-sort-Bubble-Sort</guid>
            <pubDate>Sat, 12 Oct 2024 15:32:00 GMT</pubDate>
            <description><![CDATA[<h2 id="bubble-sort">Bubble Sort</h2>
<h3 id="정의--인접한-두-원소를-비교하여-큰-수를-계속해서-뒤로-보내-정렬-하는-방식">정의 : 인접한 두 원소를 비교하여, 큰 수를 계속해서 뒤로 보내 정렬 하는 방식.</h3>
<ul>
<li>시간복잡도 O(n^2)</li>
<li>대규모 데이터에는 부적합 -&gt; 퀵 정렬, 병합 정렬을 주 사용.</li>
</ul>
<h3 id="버블-정렬-작동-원리">버블 정렬 작동 원리</h3>
<ol>
<li>첫번째 항목부터 마지막 항목까지 순차적으로 이동하면서 인접한 항목을 비교한다.</li>
<li>인접한 두 항목을 비교하면서 왼쪽항목(A[j]) 이 오른쪽 항목 보다(A[j+1]) 크면 위치를 바꾼다.</li>
<li>위의 과정을 반복한다.</li>
</ol>
<pre><code class="language-java">package javastudy;

public class bubbleSort {
  public static void bs(int a[]){
    int n = a.length; // 배열 길이.
    boolean swapped;
    int temp;

    for (int i = 0; i &lt; n -1; i++){
      swapped = false; // 스왑 여부 초기화
      for (int j = 0; j &lt; n-i-1; j++){
        if(a[j]&gt;a[j+1]){
          temp = a[j];
          a[j] = a[j+1];
          a[j+1] = temp;
          swapped = true;
        }
      }
      if (!swapped){
        break;
      }
    }
  }

  public static void printArray(int a[]){
    for (int num : a){
      System.out.print(num+&quot; &quot;);
    }
  }

  public static void main(String[] args) {
    int a[] = {8,5,6,2,4};
    System.out.println(&quot;정렬전&quot;);
    printArray(a);
    System.out.println(&quot;정렬후&quot;);
    bs(a);
    printArray(a);
  }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Graph]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Graph</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Graph</guid>
            <pubDate>Wed, 09 Oct 2024 16:20:29 GMT</pubDate>
            <description><![CDATA[<h3 id="graph그래프">Graph(그래프)</h3>
<ul>
<li>비선형 자료구조</li>
<li>점 : 노드(Node),정점(Vertex)</li>
<li>선 : link,edge(간선)</li>
<li>degree : 정점(vertex)에 부속된 간선(edge) 수</li>
</ul>
<h3 id="그래프-종류">그래프 종류</h3>
<ul>
<li>무방향 그래프 : 두 정점을 연결하는데 간선에 방향이 없는 그래프</li>
<li>방향 그래프 : 두 정점을 연결하는데 간선에 방향이 있는 그래프</li>
<li>완전 그래프 : 모든 정점들이 연결되고, 최대 간선수를 가지는 그래프</li>
<li><blockquote>
<p>n개 정점에서 무뱡향 &amp; 완전그래프 최대 간선 수 : n(n-1)/2</p>
</blockquote>
</li>
<li><blockquote>
<p>n개 정점에서 뱡향 &amp; 완전그래프 최대 간선 수 : n(n-1)</p>
</blockquote>
</li>
<li>부분 그래프 : 일부 정점이나 간선을 제외하여 만든 그래프</li>
<li>가중 그래프 : 간선에 가중치를 할당한 그래프</li>
<li>유향 비순환 그래프 : 방향그래프에서 cycle이 없는 그래프</li>
<li>연결 그래프 : 떨어져있는 정점이 없는 그래프</li>
<li>단절 그래프 : 떨어져있는 정점이 있는 그래프</li>
</ul>
<h3 id="spinning-tree">Spinning Tree</h3>
<h3 id="mstminimum-spinning-tree">MST(Minimum Spinning Tree)</h3>
<h4 id="구현하는-방법">구현하는 방법</h4>
<h5 id="1-krusals-algorithm">1. krusal&#39;s Algorithm</h5>
<h5 id="2-prims-algorithm">2. prim&#39;s Algorithm</h5>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Heap]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Heap</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Heap</guid>
            <pubDate>Sun, 06 Oct 2024 13:42:54 GMT</pubDate>
            <description><![CDATA[<h3 id="heap">Heap</h3>
<ul>
<li>완전 이진 트리 일종.</li>
<li>힙(Heap)은 삽입 및 삭제 연산에 있어서 뛰어난 성능</li>
<li>최대힙,최소힙 =&gt; 최대,최소를 찾을때 좋음</li>
</ul>
<h4 id="시간-복잡도">시간 복잡도</h4>
<ul>
<li>삽입: O(log n)</li>
<li>삭제(최대 또는 최소): O(log n)</li>
<li>접근(최대 또는 최소): O(1)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Tree]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Tree</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Tree</guid>
            <pubDate>Sun, 06 Oct 2024 09:42:48 GMT</pubDate>
            <description><![CDATA[<h3 id="자료구조-tree">자료구조 tree</h3>
<ul>
<li>하나의 루트 노드를 갖는 계층형 자료구조</li>
<li>degree: 노드의 차수 -&gt; 한 노드가 가지는 서브 노드의 수.</li>
</ul>
<h3 id="binary-tree--이진-트리-">Binary Tree ( 이진 트리 )</h3>
<ul>
<li>각 노드의 degree가 2이하인 tree로 왼쪽,오른쪽 서브트리로 구성.</li>
</ul>
<ol>
<li>포화 이진 트리</li>
</ol>
<ul>
<li>모든 leaf노드들의 level이 동일하며, 내부노드들의 degree가 2</li>
</ul>
<ol start="2">
<li>완전 이진 트리</li>
</ol>
<ul>
<li>포화 이진트리의 leaf노드들이 오른쪽부터 삭제된 트리</li>
</ul>
<h3 id="binary-search-tree-bst-이진-탐색-트리">Binary Search Tree (BST, 이진 탐색 트리)</h3>
<ul>
<li><p>이진트리 형태로 각 노드의 왼쪽 서브트리에는 부모 노드보다 작은 값이, 오른쪽 서브트리에는 부모 노드보다 큰 값이 위치하는 트리</p>
</li>
<li><p>흐름</p>
</li>
</ul>
<blockquote>
<ol>
<li>시작은 루트</li>
<li>이진 탐색 트리가 null이면 실패.</li>
<li>root의 키값이 = x 이면, 탐색은 성공하며 종료</li>
<li>키값 &lt; x 이면, 왼쪽 서브트리에서 탐색.
키값 &gt; x 이면 , 오른쪽 서브트리에서 탐색.</li>
</ol>
</blockquote>
<pre><code class="language-java">package javastudy;

import com.sun.source.tree.Tree;

// 트리 구조 노드 연결리스트.
class TreeNode {
  int value;
  TreeNode left;
  TreeNode right;

  public TreeNode(int value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}
public class tree {
  TreeNode root; //루트 노드 선언.

  public void insert(int value) {
    TreeNode newNode = new TreeNode(value);
    if (root == null) { //root가 없으면?
      root = newNode; //새로 생성된 node가 root
    }else{ //root가 있다면?
      TreeNode current = root;// current 변수는 root를 가리킴.

      //비교해야함.
      while (true) {
        if (value &lt; current.value) {
          if (current.left == null) {//왼쪽 서브트리가 없다면
            current.left = newNode;//왼쪽에 서브트리노드를 생성
            return;
          }
          current = current.left; //왼쪽에 서브트리가 있으면 왼쪽 서브트리로 이동.
        } else if (value &gt; current.value) {
          if (current.right == null) {
            current.right = newNode;
            return;
          }
          current = current.right; // 오른쪽 서브트리로 이동
        }
      }
    }
  }

  public void delete(int value) {
    root = deleteNode(root,value);
  }

  TreeNode deleteNode(TreeNode node, int value) {
    if (node == null) {
      return null;// 찾는 노드가 존재하지 않는다.
    }

    if (value &lt; node.value) {
      node.left = deleteNode(node.left,value); //왼쪽 서브트리 삭제.
    } else if (value &gt; node.value) {
      node.right = deleteNode(node.right,value);// 오른쪽 서브트리 삭제.
    }else{
      //삭제할 노드가 발견됨 -&gt; 자식이 없는경우 총 3가지로 구분
      //1. 해당 노드의 자식이 없는경우
      if(node.left == null &amp;&amp; node.right == null){
        return null; // 해당 노드를 삭제.
      }
      //2. 해당 노드의 자식이 한개인 경우.
      else if(node.left == null){
        return node.right; //오른쪽 자식노드로 대체.
      }else if(node.right == null){
        return node.left; //왼쪽 자식노드로 대체
      }else {
        //3.해당 노드의 자식이 두개인 경우.
        TreeNode successor = node.right; //오른쪽 서브트리에서 최소값을 찾았을때.
        while(successor.left != null){ //자식노드의 왼쪽이 비어있다면
          successor = successor.left;
        }
      }


    }
    return node;
  }
  // 특정 값 검색
  public boolean search(int value) {
    TreeNode current = root;

    while (current != null) {//노드가 있다..
      if (current.value == value) {
        return true; // 값이 존재하는 경우
      } else if (value &lt; current.value) {
        current = current.left; // 왼쪽으로 이동
      } else {
        current = current.right; // 오른쪽으로 이동
      }
    }

    return false; // 값이 존재하지 않는 경우
  }

  //전위 순회
  public void preOrder(){
    preOrderTraversal(root);

  }
  private void preOrderTraversal(TreeNode node){
    if(node != null){
      System.out.print(node.value +&quot; &quot;);
      preOrderTraversal(node.left);
      preOrderTraversal(node.right);
    }
  }
  //중위 순회
  public void inOrder(){
    inOrderTraversal(root);
  }
  private void inOrderTraversal(TreeNode node){
    if(node != null){
      inOrderTraversal(node.left);
      System.out.print(node.value+&quot; &quot;);
      inOrderTraversal(node.right);
    }
  }
  public void postOrder(){
    postOrderTraversal(root);
  }
  //후위 순회
  private void postOrderTraversal(TreeNode node){
    if(node != null){
      postOrderTraversal(node.left);
      postOrderTraversal(node.right);
      System.out.print(node.value+&quot; &quot;);
    }
  }

  public static void main(String[] args) {
    tree t = new tree();

    t.insert(50);
    t.insert(30);
    t.insert(20);
    t.insert(40);
    t.insert(70);
    t.insert(60);
    t.insert(80);

    t.inOrder(); //20 30 40 50 60 70 80
    t.postOrder();//20 40 30 60 80 70 50  
    t.preOrder();//50 30 20 40 70 60 80 


  }

}

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Stack]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Stack</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Stack</guid>
            <pubDate>Fri, 27 Sep 2024 17:01:18 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">public class stack {
    int maxstacksize;//stack 최대 사이즈
    int[] stackArrary;//스택 배열
    int top;//현위치

    public stack(int size) {
        this.maxstacksize = size;
        this.stackArrary = new int[maxstacksize];
        this.top = -1;
    }

    public boolean isfull() {
        return (top == maxstacksize - 1);
    }

    public boolean isEmpty() {
        return (top == -1);
    }

    public void push(int data) {
        if (isfull()) {
            System.out.println(&quot;스택이 꽉찼다.&quot;);
        } else{
            stackArrary[++top] = data;
        }
    }

    public int pop() {
        if (isEmpty()) {
            System.out.println(&quot;스택이 비어있다.&quot;);
            return -1;
        }
        return stackArrary[top--];
    }

    public int peek() {
        return stackArrary[top];
        //return stackArray[maxstacksize-1];
    }

    public void size() {
        System.out.println(&quot;현재 스택에 차있는 크기는 : &quot;+(top+1)+&quot;입니다.&quot;);
    }
    public void printAll() {
        if (isEmpty()) {
            System.out.println(&quot;스택이 비어 있습니다.&quot;);
            return;
        }
        System.out.println(&quot;스택 요소: &quot;);

        for (int i = top; i &gt;= 0; i--) {
            System.out.println(stackArrary[i] + &quot; &quot;);  // 최상위 요소부터 출력
        }
        System.out.println();  // 줄 바꿈
    }

    public static void main(String[] args) {
        stack st = new stack(5);

        st.push(1);
        st.push(2);
        st.push(3);
        st.printAll();

        st.size();
        st.peek();

        st.pop();
        st.printAll();
    }

}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - Queue]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Queue</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Queue</guid>
            <pubDate>Fri, 27 Sep 2024 17:00:04 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">
class Node{
    int data;
    Node next;

    int size;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}public class queue {
    int size;
    Node front;
    Node rear;

    public queue() {
        this.front = null;
        this.rear = null;
        this.size = 0;
    }


    public boolean isEmpty() {
        return (size == 0);
    }

    public void enqueue(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            front = newNode;
            rear = newNode;
        }else{
            rear.next = newNode;
            rear = newNode;
        }
        size++;
    }

    public int dequeue() {
        if (isEmpty()) {
            System.out.println(&quot;큐가 비어 있습니다.&quot;);
            return -1;  // 에러 코드
        }
        int dequeuedValue = front.data; // 제거할 값 저장
        front = front.next; // front를 다음 노드로 갱신
        size--; // 크기 감소
        if (isEmpty()) {
            rear = null; // 큐가 비어 있으면 rear도 null로 설정
        }
        return dequeuedValue; // 제거한 값 반환
    }

    public int peek() {
        if (isEmpty()) {
            System.out.println(&quot;큐가 비어있네?&quot;);
            return -1;
        }
        return front.data;
    }

    public int size() {
        return size;
    }

    public void printAll() {
        if (isEmpty()) {
            System.out.println(&quot;큐가 비어있다&quot;);
            return;
        }
        Node current = front; // 현재 노드를 front로 초기화
        System.out.print(&quot;현재 큐 상태: &quot;);
        while (current != null) { // 현재 노드가 null이 아닐 동안 반복
            System.out.print(current.data + &quot; &quot;); // 데이터 출력
            current = current.next; // 다음 노드로 이동
        }
        System.out.println(); // 줄 바꿈
    }

    public static void main(String[] args) {
        queue q = new queue();
        q.enqueue(1);
        q.enqueue(2);
        q.enqueue(3);
        q.enqueue(5);
        q.printAll();

    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 - 연결리스트(LinkedList)]]></title>
            <link>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8LinkedList</link>
            <guid>https://velog.io/@seungho7-1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8LinkedList</guid>
            <pubDate>Fri, 27 Sep 2024 14:03:47 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">public class LinkedList {
    Node head;
    int size = 0;
    class Node{
        int data;
        Node next;
        Node(int data) {
            this.data = data;
            this.next = null;
        }
    }


    public void addFirst(int data) {
        Node newNode = new Node(data);//새로운 노드 생성

        newNode.next = head; //이 전 head를 가리켜야함.
        head = newNode;// newNode가 head다.
        size++;
    }

    public void addLast(int data) {
        Node newNode = new Node(data);//새로운 노드 생성
        if (head == null) {
            head = newNode;
            size++;
        }else{
            Node temp = head; //임시변수를 head라고 하자
            while (temp.next != null) {
                temp = temp.next; //다음 노드로 이동.
            }
            temp.next = newNode;
            size++;

        }

    }

    public void printList() {
        Node temp = head;  // 임시 변수로 head를 사용
        while (temp != null) {
            System.out.print(temp.data + &quot; -&gt; &quot;);  // 현재 노드의 데이터 출력
            temp = temp.next;  // 다음 노드로 이동
        }
        System.out.println(&quot;null&quot;);  // 리스트의 끝을 나타내기 위해 null 출력
        System.out.println(&quot;총 리스트 크기는: &quot;+ size);
    }
    public void insert(int data, int position) {
        Node newNode = new Node(data);

        //position이 맨앞이면?
        if (position == 0) {
            addFirst(data);
        }
        Node temp = head;
        // 첫번째 포지션부터 마지막 포지션까지 접근하는데...
        for (int i = 0; i &lt; position - 1; i++) {
            if (temp == null) { // 임시 변수(헤드)가 아무것도 가리키지 않는다면?
                System.out.println(&quot;position에 벗어난것같다.&quot;);
            }
            // 임시변수가 뭐라도 건드린다면?
            temp = temp.next; // 다음 노드로이동
        }
        newNode.next = temp.next;
        temp.next = newNode;
        size++;
    }

    public void delete(int key) {
        Node temp = head;// 임시변수가 헤드를
        Node prev = null; // 이전 노드

        if (temp == null) { // 임시변수가 아무 값도 안가리키면?
            System.out.println(&quot;리스트가 비어 있습니다.&quot;);
        }

        //첫번째 노드 삭제

        if (temp != null &amp;&amp; temp.data == key) {
            head = temp.next;
            size--;
            return;
        }
        //나머지 노드 삭제
        while (temp != null &amp;&amp; temp.data != key) {
            prev = temp;
            temp = temp.next;
        }
        if (temp == null) {
            System.out.println(&quot;노드를 찾을 수 없습니다. &quot; +key);
        }
        prev.next = temp.next;

    }

    // 연결 리스트에서 특정 요소 검색 메서드
    public boolean search(int key) {
        Node temp = head;  // 임시 변수로 head를 사용
        while (temp != null) {
            if (temp.data == key) {
                return true;  // 요소를 찾으면 true 반환
            }
            temp = temp.next;  // 다음 노드로 이동
        }
        return false;  // 요소를 찾지 못하면 false 반환
    }
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.addLast(3);

        linkedList.addFirst(1);
        linkedList.addFirst(2);
        linkedList.addLast(4);
        linkedList.addLast(5);
        // 2-&gt; 1 -&gt; 3 -&gt;4 -&gt;5
        linkedList.printList();
        linkedList.insert(8,2);
        // 2-&gt; 1 -&gt; 8 -&gt; 3 -&gt;4 -&gt;5
        linkedList.printList();
        linkedList.insert(15,4);
        // 2 -&gt; 1 -&gt;8 -&gt; 3 -&gt; 15 -&gt; 4 -&gt; 5
        linkedList.printList();
        linkedList.delete(2);

        linkedList.printList();

    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스 테이블 만들기]]></title>
            <link>https://velog.io/@seungho7-1/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%85%8C%EC%9D%B4%EB%B8%94-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@seungho7-1/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%85%8C%EC%9D%B4%EB%B8%94-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 02 Sep 2024 20:35:10 GMT</pubDate>
            <description><![CDATA[<h2 id="k리그-포탈-및-트랜스퍼마켓을-기반으로-k-league-관계형-데이터베이스-기반으로-테이블을-만들보겠다">K리그 포탈 및 트랜스퍼마켓을 기반으로 k-league 관계형 데이터베이스 기반으로 테이블을 만들보겠다.</h2>
<h3 id="축구선수-성과-분석-시스템">축구선수 성과 분석 시스템.</h3>
<ul>
<li>Mysql</li>
<li>관계형 데이터베이스로 설계.</li>
</ul>
<h3 id="주요-테이블">주요 테이블</h3>
<ul>
<li>players: 선수 정보</li>
<li>player_stats: 선수별 경기 통계(득점,슈팅,도움,드리블,패스,출전경기수)</li>
<li>teams: 각 팀 정보</li>
<li>teams_stats: 각 팀 스탯(승,무,패 등)</li>
</ul>
<h2 id="players-테이블">players 테이블</h2>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/62c8e296-2f92-4c2e-acf2-26acb54782c8/image.png" alt=""></p>
<h2 id="player_stats-테이블">player_stats 테이블</h2>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/931bf7fc-003a-4c4d-8b8d-f572a5cf4581/image.png" alt=""></p>
<h2 id="teams-테이블">teams 테이블</h2>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/e8b6290c-053b-4760-b90f-09e5dae08d31/image.png" alt=""></p>
<h2 id="teams_stats-테이블">teams_stats 테이블</h2>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/b9ca5590-bee4-4304-be7f-2c5b613c37ad/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SSH agent]]></title>
            <link>https://velog.io/@seungho7-1/SSH-agent</link>
            <guid>https://velog.io/@seungho7-1/SSH-agent</guid>
            <pubDate>Sat, 31 Aug 2024 16:54:58 GMT</pubDate>
            <description><![CDATA[<h1 id="ssh-agent">SSH Agent</h1>
<h3 id="ssh-에이전트ssh-agent는-ssh-키의-비공개-키를-메모리에-저장하고-관리하는-프로그램-이를-통해-사용자는-비밀번호-입력-없이-ssh-키를-사용하여-여러-ssh-연결을-쉽게-관리">SSH 에이전트(SSH Agent)는 SSH 키의 비공개 키를 메모리에 저장하고 관리하는 프로그램. 이를 통해 사용자는 비밀번호 입력 없이 SSH 키를 사용하여 <em>여러 SSH 연결을</em> 쉽게 관리.</h3>
<h1 id="ssh-key-vs-ssh-agent">SSH Key vs SSH Agent</h1>
<h3 id="ssh-key는-ssh-프로토콜을-사용하여-인증을-수행하는-암호화-키">ssh-key는 SSH 프로토콜을 사용하여 인증을 수행하는 암호화 키.</h3>
<ul>
<li>비공개 키는 사용자만 알고 있어야함.
공개 키는 서버(진입하려는 서버 = authorized_keys)에 저장되어, 클라이언트가 인증을 요청할 때 서버가 클라이언트를 신뢰(known_hosts)하는지 확인.</li>
</ul>
<h3 id="ssh-에이전트는-ssh-클라이언트가-비공개-키를-메모리에-저장하고-관리-사용자가-비밀번호를-입력하지-않고도-여러-ssh-연결하게-하는-것">SSH 에이전트는 SSH 클라이언트가 비공개 키를 메모리에 저장하고 관리. 사용자가 비밀번호를 입력하지 않고도 <em>여러 SSH 연결하게</em> 하는 것.</h3>
<ul>
<li>비공개 키를 메모리에 보관하고, SSH 연결 시 자동으로 인증을 수행. 
사용자가 처음 한 번만 비밀번호를 입력하면, 이후에는 자동으로 인증을 처리.</li>
</ul>
<h2 id="매번-key-파일을-지정하는것이-귀찮음---agent로-처리">매번 key 파일을 지정하는것이 귀찮음. -&gt; agent로 처리.</h2>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/9fc41dc9-b722-44fa-a34c-743b515521ac/image.png" alt=""></p>
<h3 id="open-ssh로-agent를-띄우기">open-ssh로 agent를 띄우기.</h3>
<h3 id="키-파일-추가삭제">키 파일 추가/삭제</h3>
<pre><code>$ssh-add ~/.ssh/id_rsa
$ssh-add -d ~/.ssh/id_rsa</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[SSH]]></title>
            <link>https://velog.io/@seungho7-1/SSH</link>
            <guid>https://velog.io/@seungho7-1/SSH</guid>
            <pubDate>Sat, 31 Aug 2024 16:33:30 GMT</pubDate>
            <description><![CDATA[<h1 id="ssh">SSH</h1>
<ul>
<li>원격 호스트에 접속하기 위한 프로토콜</li>
<li>port = 22 (변경 가능)</li>
</ul>
<h3 id="shell---os기능을-user가-사용할-수-있게-하는-프로그램">shell -&gt; os기능을 user가 사용할 수 있게 하는 프로그램</h3>
<ul>
<li>GUI</li>
<li>CLI</li>
</ul>
<h3 id="vmware---kali-linux-서버를-putty를-이용하여-ssh로-진입해보기">Vmware -&gt; kali-linux 서버를 putty를 이용하여 ssh로 진입해보기.</h3>
<h4 id="1-ssh-server--port-확인">1. ssh server  port 확인</h4>
<pre><code>$netstat -na | grep
또는 
$nmap localhost</code></pre><h4 id="2-ssh-install">2. ssh install</h4>
<pre><code>$sudo apt install ssh</code></pre><h4 id="3-ssh-서비스-시작">3. ssh 서비스 시작</h4>
<pre><code>$ssh service ssh start</code></pre><h4 id="4-ssh-상태-확인">4. ssh 상태 확인</h4>
<pre><code>$systemctl status ssh</code></pre><h4 id="5-ip-a-명령어를-통해-kali-ip주소를-확인">5. ip a 명령어를 통해 kali ip주소를 확인.</h4>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/765ef87e-5f50-4aca-833f-9fa299669b31/image.png" alt=""></p>
<h5 id="ip-주소는-eth0이더넷-1921688129-인것을-확인">ip 주소는 eth0(이더넷) 192.168.8.129 인것을 확인.</h5>
<h3 id="putty에서-ssh로-진입">putty에서 ssh로 진입</h3>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/5613ba77-2161-4541-9f16-8ad3a6a1e30c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/739b43df-8909-4ffe-90b0-45a69f929ee5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/dee6625a-c6d6-49b1-8292-8df77314d78a/image.png" alt=""></p>
<h4 id="ssh로-진입성공">ssh로 진입성공.</h4>
<h2 id="ssh-key">SSH Key</h2>
<h4 id="ssh로-접속하는-방법은-여려가지가-있다">ssh로 접속하는 방법은 여려가지가 있다.</h4>
<h4 id="1-id와--password로-접속하는-방법">1. ID와  Password로 접속하는 방법.</h4>
<h4 id="--보안상-문제-타이핑의-존재-등">-&gt; 보안상 문제, 타이핑의 존재 등..</h4>
<h4 id="2-ssh-key를-이용하는-방법">2. SSH Key를 이용하는 방법</h4>
<h5 id="ssh-키는-두-개의-키-쌍으로-구성">SSH 키는 두 개의 키 쌍으로 구성.</h5>
<h5 id="--공개-키-public-key-다른-사람과-공유할-수-있는-키로-서버에-저장">- 공개 키 (Public Key): 다른 사람과 공유할 수 있는 키로, 서버에 저장.</h5>
<h5 id="--비공개-키-private-key-개인적으로-보관해야-하는-키">- 비공개 키 (Private Key): 개인적으로 보관해야 하는 키</h5>
<pre><code>$ssh-keygen -t rsa
## RSA 알고리즘을 이용한 키 만들기 ##</code></pre><p><img src="https://velog.velcdn.com/images/seungho7-1/post/aa51a102-2cde-4ccc-8491-38369df6f8a6/image.png" alt=""></p>
<h4 id="ssh-key-파일-확인">ssh key 파일 확인</h4>
<pre><code>$ls -la $HOME/.ssh/id_rsa*   </code></pre><p><img src="https://velog.velcdn.com/images/seungho7-1/post/d684941a-ab49-4a4b-a150-49446eec2ad5/image.png" alt=""></p>
<h4 id="ssh-key를-이용하여-접근-허용-목록에-등록해보기">SSH Key를 이용하여 접근 허용 목록에 등록해보기.</h4>
<pre><code>$cd ~/.ssh
$cat id_rsa.pub &gt; authorized_keys</code></pre><h4 id="--허용-목록에-진입하려는-서버의-key를-등록하는것">-&gt; 허용 목록에 진입하려는 서버의 key를 등록하는것.</h4>
<pre><code>$ssh localhost</code></pre><p><img src="https://velog.velcdn.com/images/seungho7-1/post/5c7a8211-54cf-49d1-9796-e7c24a9bf7ef/image.png" alt=""></p>
<h4 id="접근-목록에-공개키를-저장했기에-비밀번호-입력없이-자동으로-로그인이-가능함">접근 목록에 공개키를 저장했기에 비밀번호 입력없이 자동으로 로그인이 가능함.</h4>
<p><img src="https://velog.velcdn.com/images/seungho7-1/post/6930ced3-5d86-45d3-ae03-a2ef527110e3/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Socket에 대하여 (4) - TCP
]]></title>
            <link>https://velog.io/@seungho7-1/Socket%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-3-TCP</link>
            <guid>https://velog.io/@seungho7-1/Socket%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-3-TCP</guid>
            <pubDate>Tue, 17 Oct 2023 16:01:25 GMT</pubDate>
            <description><![CDATA[<h1 id="tcp">TCP</h1>
<h3 id="1-tcp-socket-descriptor-와-udp-socket-descriptor는-동일-하게-취급">1. TCP Socket descriptor 와 UDP Socket descriptor는 동일 하게 취급</h3>
<pre><code class="language-cpp">#include &lt;arpa/inet.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;unistd.h&gt;
#include &lt;iostream&gt;
using namespace std;

int main(){
    int s1= socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    cout&lt;&lt;&quot; UDP SOCKET ID:&quot;&lt;&lt;s1&lt;&lt;endl;

    int s2 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    cout&lt;&lt;&quot; TCP SOCKET ID:&quot;&lt;&lt;s2&lt;&lt;endl;
    close(s1);

    int s3 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    cout&lt;&lt;&quot; TCP SOCKET ID:&quot;&lt;&lt;s3&lt;&lt;endl;

    close(s2);
    close(s3);

    return 0;
    }</code></pre>
<ul>
<li><p>같은 descriptor 일지라도 완전히 다른 소켓이므로 다르다.</p>
<h3 id="2-동시에-열-수-있는-descriptor-수">2. 동시에 열 수 있는 descriptor 수</h3>
</li>
<li><p>TCP에서 동시에 열수 있는 descriptor수는 1024</p>
</li>
<li><p>descriptor 수 조정 방법</p>
<blockquote>
<p>-$ ulimit -n 1023  // 1023으로 descriptor수 증가</p>
</blockquote>
<h3 id="3-연결-하지-않고-socket에-데이터-쓰기">3. 연결 하지 않고 socket에 데이터 쓰기</h3>
<pre><code class="language-cpp">int s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 cout&lt;&lt;&quot; TCP SOCKET ID:&quot;&lt;&lt; s &lt;&lt;endl;

 char buf[1024];
 int r = send(s,buf,sizeof(buf),MSG_NOSIGNAL);</code></pre>
<ul>
<li>connect() 함수 없이 데이터를 쓴 경우 Broken Pipe(EPIPE) 로 실패.
os가 강제로 프로세스 종료</li>
<li>하지만, MSG_NOSIGNAL flag 가 종료 되는 것을 방지.</li>
</ul>
<h3 id="4-연결을-닫은-socket에-데이터-쓰기">4. 연결을 닫은 socket에 데이터 쓰기</h3>
<pre><code class="language-cpp">int s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
cout&lt;&lt;&quot; TCP SOCKET ID:&quot;&lt;&lt; s &lt;&lt;endl;

close(s);

char buf[1024];
int r = send(s,buf,sizeof(buf),MSG_NOSIGNAL);
</code></pre>
</li>
<li><p>소켓을 닫고 데이터를 보내려고하면 Bad file descripotr 에러 발생</p>
</li>
<li><p>socket descriptor가 종료 되어있기 때문이다.(존재 하지 않음.)</p>
<h3 id="5--tcp-연결-후-데이터-전송-및-수신">5.  TCP 연결 후 데이터 전송 및 수신</h3>
<pre><code class="language-cpp">#include &lt;arpa/inet.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/socket.h&gt;
</code></pre>
</li>
</ul>
<p>#include &lt;unistd.h&gt;
#include <iostream></p>
<p>using namespace std;</p>
<p>int main(){
    int s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s &lt; 0){
        cerr&lt;&lt;&quot;socket() failed: &quot;&lt;&lt; strerror(errno)&lt;&lt;endl;
        return 1;
    }</p>
<pre><code>struct sockaddr_in sin;
memset(&amp;sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(&quot;127.0.0.1&quot;);
sin.sin_port = htons(10000);

//TCP connect()
if(connect(s,(struct sockaddr *)&amp;sin, sizeof(sin)) &lt; 0){
    cerr&lt;&lt;&quot;connect() failed: &quot;&lt;&lt; strerror(errno)&lt;&lt;endl;
    return 1;
}

char buf[1024];//데이터 보내기 1024bytes를 보낸 거임.
int r = send(s,buf,sizeof(buf),MSG_NOSIGNAL);
if(r &lt; 0){
    cerr&lt;&lt;&quot;send() failed: &quot;&lt;&lt; strerror(errno)&lt;&lt;endl;}
else if(r == 0){
        cout&lt;&lt;&quot;socket closed&quot;&lt;&lt;endl;
}
else { 
    cout&lt;&lt;&quot;Sent : &quot;&lt;&lt;r&lt;&lt;&quot;bytes&quot;&lt;&lt;endl;
}

r = recv(s,buf,sizeof(buf),0); //데이터 수신하기

if(r &lt; 0){
    cerr&lt;&lt;&quot;recv() failed: &quot;&lt;&lt; strerror(errno)&lt;&lt;endl;}
    else if(r == 0){
    cerr&lt;&lt;&quot;Socket Closed&quot;&lt;&lt; endl; //recv() ==0 일때 연결 끊김상태
    }
    else{ 
    cout&lt;&lt;&quot;received : &quot;&lt;&lt;r&lt;&lt;&quot;bytes&quot;&lt;&lt;endl;
    }
close(s);
return 0;</code></pre><p>}</p>
<pre><code>
### 6. TCP active socket, passive socket
- active socket : 연결 맺어진 상태
&gt; 클라이언트 : connect() 성공 뒤 socket
서버 : accept() 성공뒤 socket

- passive socket : 연결 맺기 전 대기상태
&gt; 서버측 : listen() 성공뒤 socket

```cpp
#include &lt;arpa/inet.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/socket.h&gt;

#include &lt;unistd.h&gt;
#include &lt;iostream&gt;

using namespace std;

int main(){
    int passiveSock = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(10000); //server 주소 포트번호


//bind() -&gt; 클라이언트 i
    if(bind(passiveSock,(struct sockaddr *) &amp;sin,sizeof(sin)) &lt; 0) {
        cerr&lt;&lt; &quot;bind() failed: &quot;&lt;&lt; strerror(errno)&lt;&lt;endl;
        return 1;
    }

//listen() passive socket
    if(listen(passiveSock , 10) &lt; 0){
        cerr&lt;&lt;&quot;listen() failed: &quot;&lt;&lt;strerror(errno)&lt;&lt;endl;
        return 1;
    }

//accept() activer socket
    memset(&amp;sin,0,sizeof(sin));
    unsigned int sin_len = sizeof(sin);
    int clientSock = accept(passiveSock,(struct sockaddr *) &amp;sin, &amp;sin_len);

    if(clientSock &lt;0){
        cerr&lt;&lt; &quot;accept() failed: &quot;&lt;&lt;strerror(errno)&lt;&lt;endl;
        return 1;
    }

//받을 데이터 버퍼 크기
    char buf[65536];
    int numrecv = recv(clientSock,buf,sizeof(buf),0); //recv()
    //recv() == 0 이면 연결이 끊긴다
    if(numrecv == 0){
            cout&lt;&lt;&quot;Socket closed&quot;&lt;&lt;clientSock&lt;&lt; endl;
        }
        else if(numrecv &lt; 0){
            cerr&lt;&lt;&quot;recv() failed: &quot;&lt;&lt;strerror(errno)&lt;&lt;endl;
        }
        else { 
        cout&lt;&lt;&quot;received : &quot;&lt;&lt;numrecv&lt;&lt;&quot;bytes , cliendsock&quot;&lt;&lt; clientSock &lt;&lt;endl;
        }

        int offset = 0;
        while(offset &lt; numrecv){
            int numSend = send(clientSock, buf+offset, numrecv - offset,0);

            if(numSend &lt; 0){
                cerr&lt;&lt; &quot;send() failed: &quot;&lt;&lt;strerror(errno)&lt;&lt;endl;
            }else{
                cout&lt;&lt; &quot;Sent: &quot;&lt;&lt;numSend &lt;&lt;endl;
                offset += numSend;
            }
        }
        close(clientSock);
        close(passiveSock);
}</code></pre><ul>
<li>UDP vs TCP</li>
<li>-</li>
<li>UDP 서버 소켓 개수 -&gt; 1개</li>
<li>TCP 서버 소켓 개수 -&gt; 새로운 클라이언트 접속 passive socket, 클라이언트와 통신할 수 있는 actvie socket은 클라이언트 개수 만큼 필요.</li>
</ul>
<p>-
UDP 보다 TCP 가 훨씬 많은 os 부하 발생.</p>
]]></description>
        </item>
    </channel>
</rss>