<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Code Shell</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 03 Feb 2025 14:12:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Code Shell</title>
            <url>https://velog.velcdn.com/images/jinjukim-dev/profile/9bfaaa0f-5780-4387-9fa5-61382e1dedce/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Code Shell. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jinjukim-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[google cloud 이용한 이미지 업로드 처리]]></title>
            <link>https://velog.io/@jinjukim-dev/google-cloud-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@jinjukim-dev/google-cloud-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Mon, 03 Feb 2025 14:12:59 GMT</pubDate>
            <description><![CDATA[<p>앞서 firebase storage를 이용한 이미지 업로드 처리 정리글을 올리면서 무료 사용가능 storage 용량을 toyproject 개발 중에 초과할 것으로 예상되었다.
대안으로 검색해보다가 google cloud storage를 알게되었고 google cloud 또한 처음 사용해 보지만 25년 4월까지 무료크레딧으로 이용이 가능하여 이번 프로젝트에 적합하다고 생각하였다.</p>
<p>그리하여 앞서 정리했던 기능을 그대로 google cloud로 변경해보았고 google cloud 경우 검색 시 정리가 잘된글이 많아 참고하기 좋았다.</p>
<h3 id="버전정보">버전정보</h3>
<p>springboot : 3.3.3
java : 17
google cloud : 1.2.5</p>
<h3 id="0-google-cloud에서-새로운-프로젝트를-생성-후-설정">0. google cloud에서 새로운 프로젝트를 생성 후 설정</h3>
<p>google cloud storage : <a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a>
goole cloud에서 새로운 프로젝트 설정 후 cloud storage 새로운 버킷을 생성한다. 
아래 url에 정리가 잘되어있어 참고하여 설정하였다.</p>
<ul>
<li>설정 참고 url : <a href="https://padosol.tistory.com/66">https://padosol.tistory.com/66</a></li>
</ul>
<p>홈페이지에서 설정이 끝나면 프로젝트에서 google cloud 설정을 해보자</p>
<h3 id="1-springboot-gradle-설정">1. Springboot gradle 설정</h3>
<p>google cloud 관련 의존성을 추가한다.</p>
<blockquote>
<pre><code>implementation group: &#39;org.springframework.cloud&#39;, name: &#39;spring-cloud-gcp-starter&#39;, version: &#39;1.2.5.RELEASE&#39;
implementation group: &#39;org.springframework.cloud&#39;, name: &#39;spring-cloud-gcp-storage&#39;, version: &#39;1.2.5.RELEASE&#39;</code></pre></blockquote>
<h3 id="2-google-cloud-키파일-프로젝트에-등록">2. google cloud 키파일 프로젝트에 등록</h3>
<p>프로젝트 설정 시 받았던 키파일을 내부 resouces 아래에 포함하였다. 
(git사용 시 키파일이 올라가지않도록 필수로 꼭 gitignore파일에 등록해주기)
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/225c8c26-f546-4dd0-95c2-8be0698e4c58/image.png" alt=""></p>
<h3 id="3-google-cloud-config-생성">3. google cloud config 생성</h3>
<p>프로젝트 실행 시 자동으로 google cloud 정보를 받아올수 있도록 config로 설정해준다.</p>
<p>GoogleCloudStorageConfig.java</p>
<pre><code>@Bean
    public Storage storage() throws IOException {

        ClassPathResource resource = new ClassPathResource(&quot;키파일 내부경로&quot;);
        GoogleCredentials credentials = GoogleCredentials.fromStream(resource.getInputStream());
        String projectId = &quot;키파일 내부 프로젝트id&quot;;
        return StorageOptions.newBuilder()
                .setProjectId(projectId)
                .setCredentials(credentials)
                .build()
                .getService();
    }</code></pre><p>여기까지 Springboot에 google cloud 설정을 마쳤다.</p>
<p>그럼 이제 실제 내부로직을 추가해 이미지 업로드, 이미지 가져오는 기능을 추가해보자.</p>
<h3 id="1-이미지-업로드-기능-구현">1. 이미지 업로드 기능 구현</h3>
<h4 id="1-화면-구성-firebase-storage와-동일">1. 화면 구성 (firebase storage와 동일)</h4>
<p>이미지 업로드 화면 구성과 스크립트를 작성한다.</p>
<ul>
<li>ajax 결과에서 이미지가 정상적으로 업로드 되었는지 노출한다.
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/883578f0-3843-4c4c-b2d5-0163f83017c7/image.png" alt=""></li>
</ul>
<p>Mypage.html</p>
<pre><code> &lt;table&gt;
        &lt;tr&gt;
            &lt;td colspan=&quot;2&quot;&gt;
                // 프로필 이미지 노출
                &lt;img id =&quot;myImage&quot; src=&quot;업로드이후 url&quot; style=&quot;width: 200px;height: 200px;&quot;&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td colspan=&quot;2&quot;&gt;
                &lt;form id=&quot;uploadForm&quot;&gt;
                    &lt;label for=&quot;file&quot;&gt;사진&lt;/label&gt;
                    &lt;input type=&quot;file&quot; id=&quot;file&quot; name=&quot;file&quot; accept=&quot;image/*&quot; required /&gt;
                    &lt;button type=&quot;submit&quot;&gt;업로드&lt;/button&gt;
                &lt;/form&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
&lt;/table&gt;

// 이미지 업로드 해당 스크립트
$(&#39;#uploadForm&#39;).on(&#39;submit&#39;, function(event) {
        var formData = new FormData();
        formData.append(&#39;file&#39;, $(&#39;#file&#39;)[0].files[0]);

        $.ajax({
            url: &#39;/uploadImg&#39;,
            type: &#39;POST&#39;,
            async: false,
            data: formData,
            contentType: false,
            processData: false,
            success: function(response) {
                alert(response);
                location.href = &quot;/newMyPage&quot;;
            },
            error: function(xhr, status, error) {
                alert(response);
            }
        });
    });</code></pre><h4 id="2-내부-로직기능---이미지-업로드">2. 내부 로직기능 - 이미지 업로드</h4>
<ul>
<li>사용목적이 프로필 이미지이므로 아이디 당 1개 이상일 필요가 없어서 파일명을 로그인아이디로 구성하고 업로드하는 로직으로 구현하였다. (아이디가 고유한 값이기 때문에)</li>
<li>이후 코드 주석은 이전 firebase storage 이용 코드이며 비교로 남겨두었다.</li>
</ul>
<p>ImageController.java</p>
<ul>
<li><p>해당 리턴으로 ajax alert창에 노출된다.</p>
</li>
<li><p>새로운 매서드 saveImgToGCS를 추가하였다.</p>
<pre><code>@PostMapping(&quot;/uploadImg&quot;)
  public ResponseEntity&lt;String&gt; fileUpload(@RequestParam(&quot;file&quot;) MultipartFile multipartFile, HttpServletRequest request) throws IOException {
      HttpSession session = request.getSession();
      SessionVO sessionInfo = (SessionVO) session.getAttribute(SessionConst.SESSION_INFO);

      try{
          if (!multipartFile.isEmpty()) {
              //imageService.saveImg(multipartFile, sessionInfo.getId()); firebase storage
              imageService.saveImgToGCS(multipartFile, sessionInfo.getId());
          }
      }catch (Exception e){
          return ResponseEntity.status(500).body(&quot;파일 업로드 실패&quot;);
      }
      return ResponseEntity.ok(&quot;파일 업로드 성공&quot;);
  }</code></pre><p>ImageSeviceImpl.java</p>
</li>
<li><p>위와 같은 설명으로 blobInfo 업로드 시 fileName에 loginId가 들어가게 된다.</p>
</li>
<li><p>** 📍firebase storage에서는 동일 이미지명 일 시 자동업데이트 처리가 되는것으로 보였지만 goolge cloud에서는 오류가 나는것 같아 기존 프로필이 존재할 시 먼저 삭제처리를 진행하는 로직을 추가하였다.**</p>
</li>
<li><p>📍url에 특수문자(@)가 살짝 꼬여 힘들어 제외처리하고 저장하도록 수정하였다.
(이미지명에는 %40으로 변환되고, 생성된 url에서는 %2540으로 변환되어 불일치 문제)</p>
<pre><code>@Transactional
  @Override
  public int saveImgToGCS(MultipartFile multipartFile, String loginId) throws Exception {

      String fileName = loginId.replace(&quot;@&quot;, &quot;&quot;);
      String ext = multipartFile.getContentType(); // 파일의 형식 ex) JPG
      try{

          // 프로필이 존재할 경우 기존 프로필 삭제처리
          if(storage.get(&quot;toyproject&quot;, fileName) != null){
              storage.get(&quot;toyproject&quot;, fileName).delete();
          }

          // 이미지 신규 업로드
          BlobInfo blobInfo = storage.create(
                  BlobInfo.newBuilder(&quot;toyproject&quot;, fileName)
                          .setContentType(ext)
                          .build(),
                  multipartFile.getBytes()
          );

          if(blobInfo == null) throw new Exception();
      }catch (Exception e){
          e.getMessage();
          throw new Exception();
      }

      return 1;
  }</code></pre></li>
</ul>
<h4 id="2-내부-로직기능---이미지-가져오기">2. 내부 로직기능 - 이미지 가져오기</h4>
<ul>
<li>프로필이 저장되어 있지 않은 경우에는 Storage에 저장해놓은 default.png를 불러오도록 하였다.</li>
<li>마이페이지 접근 시 해당 메서드를 함께 호출하여 해당 url정보를 가져가도록 구성하고 html에서 img src로 노출하면 해당 이미지가 보이게 된다.</li>
<li>📍 <strong>cloud storage에서 제공하는 2가지 url중 인증된 url를 사용해야 업로드한 이미지로 정상적으로 보였다.</strong><ul>
<li>📍 <strong>공개된 url을 사용하니 업로드 해도 바뀐이미지로 안보이는 오류가 발생하였다.</strong></li>
</ul>
</li>
</ul>
<p>ImageSeviceImpl.java</p>
<pre><code> @Override
    public String getImgUrlFromGCS(String loginId){
        String encodedURL = &quot;&quot;;
        String fileName = loginId.replace(&quot;@&quot;, &quot;&quot;);
        try{
            if(storage.get(&quot;toyproject&quot;, fileName) == null){
                // 이미지 없는 경우 디폴트 이미지로 노출
                return &quot;https://storage.cloud.google.com/toyproject/default.png&quot;;
            }

            encodedURL = &quot;https://storage.cloud.google.com/toyproject/&quot;+fileName;

        }catch (Exception e){
            e.getMessage();
        }
        return encodedURL;
    }</code></pre><h3 id="마치며">마치며</h3>
<p>이렇게 구성하면 앞서 글과 동일한 로직으로 firebase storage에서 google storage로 변경하여 사용할 수 있다. 회사에서는 AWS S3를 이용하여 이미지처리를 하고 있어서 다른 방법을 사용해 본적이 없었는데 이번 기회에 설정을 해보았다.</p>
<h3 id="google-cloud-설정-참고-url">google cloud 설정 참고 URL</h3>
<p><a href="https://padosol.tistory.com/66">https://padosol.tistory.com/66</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Firebase Storage 이용한 이미지 업로드 처리(with Springboot )]]></title>
            <link>https://velog.io/@jinjukim-dev/Springboot-Firebase-Storage-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@jinjukim-dev/Springboot-Firebase-Storage-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Sun, 02 Feb 2025 05:34:36 GMT</pubDate>
            <description><![CDATA[<p>Springboot를 이용한 토이프로젝트 프로필 이미지처리를 위해 처음 Firebase Strorage를 사용해보았다.</p>
<ul>
<li>사용목적을 간단한 프로필 이미지 업로드 이후 마이페이지에서 노출하고 이미지를 변경하는 방법을 정리해보았다.</li>
</ul>
<h3 id="버전정보">버전정보</h3>
<p>springboot : 3.3.3
java : 17
firebase : firebase-admin:9.2.0</p>
<h3 id="1-firebase-가입-후-blaze-요금제-가입">1. firebase 가입 후 Blaze 요금제 가입</h3>
<p><a href="https://firebase.google.com/">https://firebase.google.com/</a></p>
<p>firebase strorage 이용을 위해 가입 이후에는 무료버전인 Spark 요금제인데 firebase strorage를 이용하기 위해서는 종량제 버전인 Blaze 요금제에 가입해야한다. 그러면 strorage에 1GB를 무료로 사용가능하며 이후는 사용량에 따라 요금이 부과되는 형식이다. <del>(사실 무료치고 굉장히 적긴하다..)</del></p>
<h3 id="2-firebase-프로젝트-생성-이후-설정">2. firebase 프로젝트 생성 이후 설정</h3>
<p>새로운 프로젝트를 생성한다.
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/d835178e-7158-4c36-a12c-bce71d91d664/image.png" alt=""></p>
<p>생성이후 프로젝트 설정 - 서비스 계정에서 언어에 맞는 Admin SDK 구성 스니펫코드와 키를 생성할 수 있다. 해당 코드는 이후 프로젝트에서 config 코드에 사용 예정이다. (Springboot java 사용으로 자바 코드를 복사하였다.)
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/7b026b66-c82d-416b-b3dd-50648158d990/image.png" alt=""></p>
<h3 id="3-firebase-storage를-생성한다">3. firebase Storage를 생성한다.</h3>
<p>이제부터 이곳에 이미지를 등록하고 가져와서 사용하게 된다.
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/cd6b8bb4-1655-4606-9738-f635cb5bbb35/image.png" alt=""></p>
<p>이제 프로젝트로 돌아가서 firebase 설정을 마져 해보자.</p>
<h3 id="1-springboot-gradle-설정">1. Springboot gradle 설정</h3>
<p>firebase 사용을 위해 최신버전 gradle을 받아준다.</p>
<blockquote>
<p>implementation(&quot;com.google.firebase:firebase-admin:9.2.0&quot;) // 최신 버전 확인</p>
</blockquote>
<h3 id="2-firebase-키파일-프로젝트에-등록">2. firebase 키파일 프로젝트에 등록</h3>
<p>프로젝트 내부 resouces 아래에 포함하였다. 
(git사용 시 키파일이 올라가지않도록 필수로 꼭 gitignore파일에 등록해주기)
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/68316b6c-602c-4766-8a08-d7832186b5d6/image.png" alt=""></p>
<h3 id="3-firebase-config-생성">3. firebase config 생성</h3>
<p>프로젝트 실행 시 자동으로 firebase 정보를 받아올수 있도록 config로 설정해준다.</p>
<ul>
<li>파일경로는 copy path로 Path From source Root 경로 입력해준다.</li>
<li>firebasestorage 버킷명은 gs:// 제외한 뒤에 이름을 입력해준다.</li>
</ul>
<p>bucket()</p>
<ul>
<li>이후 이미지정보를 가져오기 위해 bucket()도 config에 추가해준다.</li>
</ul>
<p>FirebaseConfig.java</p>
<pre><code>@Bean
    public FirebaseApp firebaseApp() throws IOException{

        List&lt;FirebaseApp&gt; firebaseApps = FirebaseApp.getApps();

        if (!firebaseApps.isEmpty()) {
            // 이미 초기화된 FirebaseApp이 있다면 첫 번째 FirebaseApp 반환
            return firebaseApps.get(0);
        }

        FirebaseOptions options = FirebaseOptions.builder()
                .setCredentials(
                        GoogleCredentials.fromStream(
                                new ClassPathResource(&quot;키파일 내부 위치&quot;).getInputStream()))
                .setStorageBucket(&quot;firebasestorage 버킷명&quot;)
                .build();

        FirebaseApp app = FirebaseApp.initializeApp(options);

        return app;

    }

    @Bean
    public Bucket bucket() throws IOException{
        return StorageClient.getInstance(firebaseApp()).bucket();
    }</code></pre><p>여기까지 Springboot에 firebase 설정을 마쳤다.</p>
<p>그럼 이제 실제 내부로직을 추가해 이미지 업로드, 이미지 가져오는 기능을 추가해보자.</p>
<h3 id="1-이미지-업로드-기능-구현">1. 이미지 업로드 기능 구현</h3>
<h4 id="1-화면-구성">1. 화면 구성</h4>
<p>이미지 업로드 화면 구성과 스크립트를 작성한다.</p>
<ul>
<li>ajax 결과에서 이미지가 정상적으로 업로드 되었는지 노출한다.
<img src="https://velog.velcdn.com/images/jinjukim-dev/post/883578f0-3843-4c4c-b2d5-0163f83017c7/image.png" alt=""></li>
</ul>
<p>Mypage.html</p>
<pre><code> &lt;table&gt;
        &lt;tr&gt;
            &lt;td colspan=&quot;2&quot;&gt;
                // 프로필 이미지 노출
                &lt;img id =&quot;myImage&quot; src=&quot;업로드 이후 url&quot; style=&quot;width: 200px;height: 200px;&quot;&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td colspan=&quot;2&quot;&gt;
                &lt;form id=&quot;uploadForm&quot;&gt;
                    &lt;label for=&quot;file&quot;&gt;사진&lt;/label&gt;
                    &lt;input type=&quot;file&quot; id=&quot;file&quot; name=&quot;file&quot; accept=&quot;image/*&quot; required /&gt;
                    &lt;button type=&quot;submit&quot;&gt;업로드&lt;/button&gt;
                &lt;/form&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
&lt;/table&gt;

// 이미지 업로드 해당 스크립트
$(&#39;#uploadForm&#39;).on(&#39;submit&#39;, function(event) {
        var formData = new FormData();
        formData.append(&#39;file&#39;, $(&#39;#file&#39;)[0].files[0]);

        $.ajax({
            url: &#39;/uploadImg&#39;,
            type: &#39;POST&#39;,
            async: false,
            data: formData,
            contentType: false,
            processData: false,
            success: function(response) {
                alert(response);
                location.href = &quot;/newMyPage&quot;;
            },
            error: function(xhr, status, error) {
                alert(response);
            }
        });
    });</code></pre><h4 id="2-내부-로직기능---이미지-업로드">2. 내부 로직기능 - 이미지 업로드</h4>
<ul>
<li>사용목적이 프로필 이미지이므로 아이디 당 1개 이상일 필요가 없어서 파일명을 로그인아이디로 구성하고 업로드하는 로직으로 구현하였다. (아이디가 고유한 값이기 때문에)</li>
</ul>
<p>ImageController.java</p>
<ul>
<li><p>해당 리턴으로 ajax alert창에 노출된다.</p>
<pre><code>@PostMapping(&quot;/uploadImg&quot;)
  public ResponseEntity&lt;String&gt; fileUpload(@RequestParam(&quot;file&quot;) MultipartFile multipartFile, HttpServletRequest request) throws IOException {
      HttpSession session = request.getSession();
      SessionVO sessionInfo = (SessionVO) session.getAttribute(SessionConst.SESSION_INFO);

      if (!multipartFile.isEmpty()) {
          imageService.saveImg(multipartFile, sessionInfo.getId());
          return ResponseEntity.ok(&quot;파일 업로드 성공&quot;);
      }else{
          return ResponseEntity.status(500).body(&quot;파일 업로드 실패&quot;);
      }
  }</code></pre><p>ImageSeviceImpl.java</p>
</li>
<li><p>위와 같은 설명으로 bucket에 업로드 시 fileName에 loginId가 들어가게 된다.</p>
<pre><code>@Transactional
  @Override
  public int saveImg(MultipartFile multipartFile, String loginId) throws IOException {

      String fileName = loginId;
      InputStream content = new ByteArrayInputStream(multipartFile.getBytes());

      try{
          bucket.create(fileName, content, multipartFile.getContentType());
      }catch (Exception e){
          e.getMessage();
          return 0;
      }

      return 1;
  }</code></pre></li>
</ul>
<h4 id="2-내부-로직기능---이미지-가져오기">2. 내부 로직기능 - 이미지 가져오기</h4>
<ul>
<li>프로필이 저장되어 있지 않은 경우에는 Storage에 저장해놓은 default.png를 불러오도록 하였다.</li>
<li>마이페이지 접근 시 해당 메서드를 함께 호출하여 해당 url정보를 가져가도록 구성하고 html에서 img src로 노출하면 해당 이미지가 보이게 된다.</li>
</ul>
<p>ImageSeviceImpl.java</p>
<pre><code>@Override
    public String getImgUrl(String loginId) {
        String encodedURL = &quot;&quot;;
        try{
            if(bucket.get(loginId) == null){
                // 이미지 없는 경우 디폴트 이미지로 노출
                return &quot;https://firebasestorage.googleapis.com/v0/b/firebase Storage 버킷명/o/default.png?alt=media&quot;;
            }

            String imagePath = loginId; // 이미지 파일 경로
            String encodedImgPath = URLEncoder.encode(imagePath, &quot;UTF-8&quot;);
            encodedURL = &quot;https://firebasestorage.googleapis.com/v0/b/firebase Storage 버킷명/o/&quot;+ encodedImgPath + &quot;?alt=media&quot;;

        }catch (Exception e){
            e.getMessage();
        }
        return encodedURL;
    }</code></pre><h3 id="마치며">마치며</h3>
<p><img src="https://velog.velcdn.com/images/jinjukim-dev/post/076ad547-0d40-44f1-b7fa-69ebc826b362/image.png" alt=""></p>
<p>이렇게 구성하면 이미지를 로그인아이디로 가져오고 업로드 할 수 있게 된다. 하지만 1GB까지만 무료이기 때문에 현재 테스트만으로도 67KB를 사용해버렸다. 
다음에는 같은 로직을 google cloud를 이용하는 방법으로 변경해볼까 한다.</p>
<h3 id="firebase-storage-설정-참고-url">Firebase Storage 설정 참고 URL</h3>
<p><a href="https://popawaw.tistory.com/264">https://popawaw.tistory.com/264</a>
<a href="https://bellgod.tistory.com/107">https://bellgod.tistory.com/107</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OAuth2.0]]></title>
            <link>https://velog.io/@jinjukim-dev/OAuth2.0</link>
            <guid>https://velog.io/@jinjukim-dev/OAuth2.0</guid>
            <pubDate>Thu, 04 Mar 2021 14:17:46 GMT</pubDate>
            <description><![CDATA[<h3 id="oauth20-open-auth란">OAuth2.0 (Open Auth)란?</h3>
<h3 id="oauth20-왜-사용하는-것일까">OAuth2.0 왜 사용하는 것일까?</h3>
<blockquote>
<p>실세 세상에 A라는 사람은 한 사람인데 인터넷 세상에는 사이트의 개수만큼 A가 존재하게 된다. 이러면 사이트가 많아질 수록 A의 개인정보 노출의 위험이 커진다. 이러한 노출의 위험을 줄이기 위해 한 곳에서 A의 정보를 관리하면 어떨까? 라는 개념으로 예시로 Naver, Kakao에서 개인 정보를 관리하면서 로그인 처리를 해주는 것을 말한다.
🔸 스프링의 공식 OAuth 주체 : Fackbook, google ▶ OAuth-client 라이브러리 </p>
</blockquote>
<h3 id="일반-로그인-절차">일반 로그인 절차</h3>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/29460184-63ce-41ee-9122-48b89b207281/45DBAF1F-58BD-400D-9245-103C200C10C6%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8.jpeg" alt=""></p>
<h3 id="oauth-로그인-절차">OAuth 로그인 절차</h3>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/99f483d3-0fba-4d18-a428-1e5aeb039ca4/45DBAF1F-58BD-400D-9245-103C200C10C6%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8.jpeg" alt=""></p>
<ul>
<li><strong>code</strong>를 부여 받게 되면 <strong>카카오 인증처리 완료</strong>를 의미한다.</li>
<li><strong>AccessToken</strong>을 부여받게 되면 <strong>권한부여</strong>를 의미한다.<ul>
<li>권한을 부여 받으면 클라이언트 서버는 <strong>자원서버</strong>에 접근하여 홍길동의 대한 정보에 접근할 수 있다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Ajax]]></title>
            <link>https://velog.io/@jinjukim-dev/Ajax</link>
            <guid>https://velog.io/@jinjukim-dev/Ajax</guid>
            <pubDate>Tue, 02 Mar 2021 04:46:57 GMT</pubDate>
            <description><![CDATA[<h3 id="ajax란">Ajax란?</h3>
<h4 id="ajaxasynchronous-javascript-and-xml">AJAX(Asynchronous Javascript And XML)</h4>
<blockquote>
<p>Ajax는 HTML 페이지 전체가 아닌 일부만 갱신할 수 있도록 XMLHttpRequest객체를 통해 서버에 request한다. 이 경우, JSON이나 XML형태로 필요한 데이터만 받아 갱신하기 때문에 그마큼의 자원과 시간을 아낄 수 있다.
AJax가 그 자체 기술은 아니고 기존의 여러 기술을 사용하는 &quot;새로운 접근법&quot;이다. </p>
</blockquote>
<h3 id="ajax를-사용하는-이유">Ajax를 사용하는 이유</h3>
<h4 id="1-요청에-대한-응답을-html이-아닌-datajson-xml을-받기-위해서이다">1. 요청에 대한 응답을 html이 아닌 Data(json, XML)을 받기 위해서이다.</h4>
<p>요청에 대한 응답은 .html 파일로 응답하게된다. 하지만 웹이 아닌 애플리케이션의 경우 .html을 인식하지 못하기 때문에 웹과 앱 모두 사용하려면 두개의 서버가 필요하게 된다. <br/>(.html 응답 서버/data 응답 서버) </p>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/99b2f9d8-fad3-46ac-8697-6c90bf5492c0/1DBB26FA-AA3E-4553-ACB2-2DF14ED93F23.jpeg" alt=""></p>
<p>🔸 하지만 Ajax를 사용하면 웹과 앱 서버 하나로 통일하여 사용일 가능하다.</p>
<h4 id="2-비동기-통신을-하기-위해서이다">2. 비동기 통신을 하기 위해서이다.</h4>
<ul>
<li>비동기 : 하던 작업을 중단하고 다른 작업이 가능하다.</li>
<li>비동기 처리 : 일의 순서에 상관없이 처리 </li>
</ul>
<blockquote>
<p>ex) 그림판에 그림그리기 </p>
</blockquote>
<ol>
<li>화면에 그림  2. 연산 3. A그림 다운로드 4. A 그림 그리기 5. 다른 그림 그리기
동기 : 1 - 2 - 3 (3을 다운받는 동안 프로그램 stop, pending)- 4 - 5
비동기 :
1 - 2 - 3 (A그림을 다운받는 중) - 5 (3완료 call back) - 3(A그림 다운 완료) - 4 - 5 (나머지5)</li>
</ol>
<h3 id="ajax-장점단점">Ajax 장점/단점</h3>
<h4 id="ajax-장점">Ajax 장점</h4>
<ol>
<li>웹 페이지의 속도 향상</li>
<li>서버의 처리가 완료될 때까지 기다리지 않고 처리 가능 (비동기 통신)</li>
<li>서버에서 Data만 전송하면 되므로 전체적인 코딩의 양이 줄어든다.</li>
</ol>
<h4 id="ajax-단점">Ajax 단점</h4>
<ol>
<li>히스토리 관리가 안된다. (보안에 신경)</li>
<li>연속으로 뎅이터를 요청하면 서버 부하 증가</li>
<li>XMLhttpRequest를 통해 통신을 하는 경우 사용자에게 아무런 진행 정보가 주어지지 않아 아직 요청이 완료되지 않았는데 사용자가 페이지를 떠나거나 오자곧ㅇ할 우려가 발생하게 된다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Security]]></title>
            <link>https://velog.io/@jinjukim-dev/Spring-Security</link>
            <guid>https://velog.io/@jinjukim-dev/Spring-Security</guid>
            <pubDate>Thu, 25 Feb 2021 16:18:34 GMT</pubDate>
            <description><![CDATA[<h3 id="spring-security">Spring Security</h3>
<p>Spring Security는 Spring 기반의 애플리케이션의 보안(인증과 권한, 인가)을 담당하는 스프링 하위 프레임워크이다. </p>
<h4 id="시큐리티-태그-라이브러리">시큐리티 태그 라이브러리</h4>
<!-- 시큐리티 태그 라이브러리 -->
<pre><code>    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
      &lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
    &lt;/dependency&gt;</code></pre><h4 id="시큐리티를-사용한-로그인-로직">시큐리티를 사용한 로그인 로직</h4>
<p>시큐리티 ▶ 로그인 요청 ▶ 시큐리티가 <strong>가로채서</strong> 로그인 진행 후 완료 ▶ 유저 정보를 시큐리티 세션에 저장 (유저정보 IoC, type : userDetails) ▶ 해쉬 암호화 ▶ 로그인</p>
<h3 id="spring-security-로직">Spring Security 로직</h3>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/41c5a6ce-626e-443c-b817-a9e14263dc0f/F79C843E-48BA-4391-9848-46C2269C20A3.jpeg" alt=""></p>
<h3 id="정리해본-spring-security-로직">정리해본 Spring Security 로직</h3>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/c93ffbb8-ca4c-4201-b7ef-dc16b7d55668/9E7BC73E-348D-4FD6-BF31-A73A8599FACD.jpeg" alt=""></p>
<h4 id="코드">코드</h4>
<pre><code class="language-java">Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
// authentication 객체에 세션 저장
SecurityContextHolder.getContext().setAuthentication(authentication);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Springboot 동작원리]]></title>
            <link>https://velog.io/@jinjukim-dev/Springboot-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@jinjukim-dev/Springboot-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Wed, 17 Feb 2021 16:10:03 GMT</pubDate>
            <description><![CDATA[<h2 id="springboot-동작원리">Springboot 동작원리</h2>
<h3 id="1-내장-톰켓을-가진다">1. 내장 톰켓을 가진다.</h3>
<p>웹서버는 자바 코드가 추가된 파일 요청이 오면 응답하지 못하기 때문에 톰켓이 필요하다. 웹서버가 이해하지 못하는 파일에 대한 요청이 오면 제어권을 톰켓에게 넘긴다.</p>
<p>🔸 톰켓은 파일안에 있는 모든 자바코드를 컴파일하고 컴파일이 끝나면 컴파일된 데이터를 html 문서로 만들고 웹서버에게 넘겨준다.</p>
<h4 id="soket">Soket</h4>
<p>운영체제가 가지고 있는 것으로 프로그램과 프로그램, PC와 PC간의 통신을 말함.
ex) A &lt;- 메세지 교환 -&gt;B
A (소켓 오픈 포트번호 5000) A와 연결하고 싶은 B는 ip주소와 포트번호 5000번 연결하면 서로 통신 가능.
소켓통신을 이용하면 timeslice, 스레드를 이용해서 동시동작하는것처럼 가능하다.
장점 : 연결이 계속되어 있다.
단점 : 부하가 크다. 느려질 수 있음.</p>
<h4 id="http">HTTP</h4>
<p>문서를 전달하는 통신으로 http 통신은 stateless 방식을 사용한다.
장점 : 부하가 적다.
단점 : 비연결형이기 때문에 다시 연결될때 새로운 것으로 인식하게 됨.
http 확장자로 만들어진 문서를 필요한 사람에게 전송의 목적으로 만들어짐</p>
<h4 id="웹서버">웹서버</h4>
<p>내 컴퓨터 &lt;---요청 request, IP주소, URL(자원을 요청하는 주소L : location)--- 다른 컴퓨터
내 컴퓨터 ---응답 response (static 자원) ---&gt; 다른 컴퓨터
요청할 때 만 주소가 필요하다. 그러므로 요청하지 않았을 때 응답할 수 없다.</p>
<h3 id="2-서블릿-컨테이너">2. 서블릿 컨테이너</h3>
<p>자바코드로 웹을 할 수 있게 컨테이너로 모아놓은 것 -&gt; 톰켓</p>
<h4 id="servlet서블릿">Servlet(서블릿)</h4>
<p>자바를 사용하여 웹을 만들기 위해 필요한 기술로 클라이언트의 요청을 처리하고, 그 결과를 반환하는 자바 웹 프로그래밍 기술</p>
<p>client request(자바) -&gt; 서블릿 컨테이너 -&gt; 
최초요청 
-&gt; yes -&gt; 스레드 생성 -&gt; 서블릿 객체 생성 -&gt; response
-&gt; no  -&gt; 기존에 있는 스레드 재사용</p>
<p>Sevice(HttpServletRequest, HttpServletResponse) 톰켓이 생성함.</p>
<p>💡 동시에 수백,수만명의 요청이 발생할때마다 스레드와 서블릿 객체 생성 (동시 접근허용), 정해놓은 스레드 만큼 만들어지고 만들어진 스레드는 재사용된다. -&gt; 속도 향상</p>
<h4 id="url">URL</h4>
<p>자원 접근 주소요청 방식 --&gt; 스프링에서는 사용X
ex) <a href="http://naver.com/a.png">http://naver.com/a.png</a></p>
<h4 id="uri">URI</h4>
<p>식별자를 통해 접근하는 방식 --&gt; 스프링에서 사용O
특정한 파일 요청을 할 수 없다. 
요청시에는 무조건 자바를 거친다. -&gt; 무조건 제어권을 톰켓에게 넘긴다.
ex) <a href="http://naver.com/Picture/a">http://naver.com/Picture/a</a></p>
<h3 id="3-webxml">3. web.xml</h3>
<p>웹서버에 진입 시 최초로 실행, 웹실행 시 문지기같은 역할</p>
<ul>
<li>SevletContext의 초기 파라미터
초기 파라미터는 한번 설정해놓으면 어디에서든지 동작가능</li>
<li>Session의 유효시간 설정</li>
<li>Servlet/JSP에 대한 정의</li>
<li>Servlet/JSP 매핑
모든 클래스에 매핑을 적용시키기에는 코드가 복잡해지기 때문에 FromtController 패턴 이용</li>
<li>Mime Type 매핑
💡 Mime Type : 들어오는 데이터 타입을 알아야 가공 가능</li>
<li>Welcome File list</li>
<li>Error Pages 처리</li>
<li>리스너/필터 설정 
필터 : 값이 들어올때 필터를 통해서 걸러내는 역할</li>
<li>보안</li>
</ul>
<h3 id="4-frontcontroller-패턴">4. FrontController 패턴</h3>
<p>🔸 web.xml에 다 정의하기 힘들기 때문에 최초 앞단에서 request 요청을 받아서 필요한 클래스에 넘겨준다. 
이때 새로운 요청이 생기기 때문에 request와 response가 새롭게 new 될 수 있다.
그래서 아래의 RequestDispatcher가 필요하다.</p>
<p>request -&gt; 웹서버(URI or 자바파일 -&gt; 톰켓(web.xml -&gt; FromtController(특정 주소를 가져가서 내부에 어떤 자원을 찾아갈 수 있게 request를 한번 더 진행))</p>
<p>톰켓이 request(요청한 사람 정보, 들고온 데이터), response(응답해야할 객체) 자동으로 만든다.</p>
<p>💡 request는 진행될때마다 바뀌는데 다시 request를 진행할 때 기존에 request 정보를 유지 작업이 필요하다. -&gt; RequestDispatcher 이용</p>
<h3 id="5-requestdispatcher">5. RequestDispatcher</h3>
<p>필요한 클래스 요청이 도달했을 때 FrontController에 도착한 request와 response를 <strong>그대로 유지</strong> 시켜준다. 
데이터를 들고 페이지를 이동할 수 있도록 도와준다.</p>
<h3 id="6-dispatchservlet">6. DispatchServlet</h3>
<p>FrontController 패턴을 직접짜거나 RequestDispatcher를 직접구현할 필요가 없다. 왜냐하면 스프링에는 DispatchServlet이 있기 때문이다.
🔸 DispatchServlet = FrontController 패턴 + RequestDispatcher</p>
<p>DispatchServlet이 자동생성되어 질 때 수 많은 객체가 생성(IoC)된다. 보통 필터들이다. 해당 필터들은 내가 직접 등록할 수 도 있고 기본적으로 필요한 필터들은 자동 등록 됨.</p>
<p>DispatchServlet 목적
컴포넌트 스캔 -&gt; IoC 역할을 해준다. -&gt; 필요한 것들을 (필요한 것은 어노테이션으로 구분해서 선택) 메모리에 올려줌(new 해줌) -&gt; 주소분배</p>
<h3 id="7-스프링-컨테이너">7. 스프링 컨테이너</h3>
<p>DispatchServlet에 의해 생서되어지는 수 많은 객체들은 어디에서 관리될까?</p>
<p>🔸 request(요청) -&gt; web.xml -&gt; ContextLoaderListener (ApplicationContext 로드 -&gt; root-context.xml 로드(DB관련 객체 생성)) -&gt; servlet-ApplicationContext 호출 -&gt; DispatchServlet (컴포넌트 스캔 -&gt; 메모리에 올림 -&gt; 주소분배)</p>
<h4 id="contextloaderlistener">ContextLoaderListener</h4>
<p>모든 스레드가 공통적으로 사용해도 되는 것 (DB에 관련된 것)
root-ApplicationContext 파일을 읽음 (공통적으로 사용하는 스레드를 메모리에 올려줌)</p>
<h4 id="applicationcontext">ApplicationContext</h4>
<p>수 많은 객체들이 ApplicationContext에 등록되고 필요한 곳에서 ApplicationContext에 접근하여 필요한 객체를 가져올 수 있다. 이는 싱글톤으로 관리되기 때문에 어디에서 접근하든 동일한 객체라는 것을 보장해준다.</p>
<p>종류 : servlet-applicationContext, root-applicationContext</p>
<ul>
<li><p>servlet-applicationContext
웹과 관련된 정보 즉 웹과 관련된 어노테이션만 스캔(메모리에 로딩)해서 올린다.</p>
</li>
<li><p>root-applicationContext
DB관련된 객체 생성</p>
</li>
</ul>
<h4 id="bean-factory">Bean Factory</h4>
<p>필요한 객체를 Bean Factory에 등록할 수 도 있다.</p>
<pre><code class="language-java">@Configuration
Class A {
    @Bean
    객체 메소드();
    return 객체();
}</code></pre>
<p>초기에 메모리에 로드되지 않고 <span style="color:blue"><strong>필요할 때</strong></span> getBean()이라는 메소드를 통하여 호출하여 메모리에 로드</p>
<h3 id="8-요청-주소에-따른-적절한-컨트롤로-요청handler-mapping">8. 요청 주소에 따른 적절한 컨트롤로 요청(Handler Mapping)</h3>
<p>Get요청 -&gt; <a href="http://localhost:8080/post/1">http://localhost:8080/post/1</a> (URI)
해당 주소 요청이 오면 적절한 컨트롤러의 함수를 찾아서 실행</p>
<h3 id="9-응답">9. 응답</h3>
<ul>
<li>html 파일을 응답
ViewResolver(파일위치와 확장자를 앞뒤로 붙여줌)가 관여하게 된다.</li>
<li>Data를 응답 (객체)
MessageConverter가 작동하게 되는데 메시지를 컨버팅할 때 기본전략은 json이다.</li>
</ul>
<h3 id="💡-전체적인-로직-💡">💡 전체적인 로직 💡</h3>
<p>톰캣 실행 시 ▶ 1. web.xml ▶ 2. ContextLoaderListener ▶ 3. applicationContext.xml ▶ 4. (root-context.xml)SeviceImpl, DAO, VO 메모리 로딩 ▶ 5. <span style="color:blue"><strong>request 요청</strong></span> ▶  6. (servlet-context.xml)DispatchServlet (web.xml역할 분배받아 컴포넌트스캔, 주소분배) ▶ 8. 메모리에 올리기 (주소분배) ▶  9. html파일리턴? Data리턴? 선택 후 <span style="color:blue"><strong>response 응답</strong></span></p>
<h3 id="💡-springboot-로직">💡 Springboot 로직</h3>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/57b26277-b928-4027-9732-e662f284a0d8/1F5F6D04-BDFF-4007-B136-038A43F6FC09.jpeg" alt=""></p>
<h3 id="ex-로그인요청-로직으로-알아보는-작동원리">EX) 로그인요청 로직으로 알아보는 작동원리</h3>
<ol>
<li><p>클라이언트 요청
<a href="http://localhost:8000/login">http://localhost:8000/login</a> (post방식) Body data : username, password</p>
</li>
<li><p>톰캣 시작, 필터, 디스패쳐, 세션, 인터셉터, Datasource 메모리 로딩</p>
</li>
<li><p>요청이 오면 controller, Service, repository(JPA)가 스레드로 작동한다.
(다른 사용자가 요청 할때마다)</p>
</li>
<li><p>controller는 username, paseword를 @PostMapping(주소) 찾음</p>
</li>
<li><p>Service는 login() 시작</p>
</li>
<li><p>repository는 해당 username과 password가 맞는지 select 요청</p>
</li>
<li><p>DB전에 영속성 컨텐스트에 해당 user 오브젝트가 있는지 확인하고 없으면 영속성 컨텍스트가 DataSource가 DB에서 user 오브젝트를 받아 영속석 컨텐스트에 보냄</p>
</li>
<li><p>해당 user 오브젝트를 Service에 보내고 Service는 해당 user가 존재하는지 여부를 판단하여 user가 존재한다면 세션에 저장한다.
8-1. Service가 종료될때 트랜잭션이 종료되면서 Commit -&gt; DB update가 일어난다.</p>
</li>
<li><p>이러한 로그인 로직이 끝났다면 마지막에 controller로 와서 마지막 반환이 data라면(@RestController) 데이터 리턴하고 종료. 
9-1. 반환이 .html 화면이라면(@Controller) viewResolver가 실행되며 해당 화면을 찾아 화면을 리턴한다.</p>
</li>
</ol>
<h3 id="service">Service</h3>
<ul>
<li>트랜잭션의 시작과 종료</li>
<li>트랜잭션의 정상 수행 ▶ commit ▶ 서비스 종료</li>
<li>하나라도 처리되지 않았을 때 모두 Rollback 처리</li>
<li>DB에 필요한 질의요청을 repository(JPA)에 요청</li>
<li>트랜잭션 처리 ▶ 어떤 하나의 기능 ▶ DB 요청</li>
<li>여러가지 DB 요청들을 하나의 pakage에 담고 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CS 정리]]></title>
            <link>https://velog.io/@jinjukim-dev/%EC%B7%A8%EC%97%85%EC%A4%80%EB%B9%84%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91framework</link>
            <guid>https://velog.io/@jinjukim-dev/%EC%B7%A8%EC%97%85%EC%A4%80%EB%B9%84%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91framework</guid>
            <pubDate>Sat, 13 Feb 2021 08:49:36 GMT</pubDate>
            <description><![CDATA[<h2 id="📂-spring_framework">📂 Spring_framework</h2>
<h3 id="spring이란-무엇인가요">Spring이란 무엇인가요?</h3>
<p>스프링은 프레임 워크이다.</p>
<ul>
<li>개발자들이 따라야 할 가이드라인을 가진다. 시스템의 통합성과 일관성을 높이는 대신 개발자의 자유가 제한된다.</li>
<li>컴포넌트 재사용 가능</li>
<li>개발자들을 위한 다양한 도구들이 지원된다.</li>
</ul>
<h3 id="spring-boot-란">Spring Boot 란?</h3>
<p>스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용</p>
<ul>
<li>단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성</li>
<li>Tomcat 같은 웹 서버를 내장해서 별도의 웹 서버 설치 필요 없다.</li>
<li>손쉬운 빌드 구성을 위한 starter 종속성 제공</li>
</ul>
<h4 id="springboot-작동원리">springboot 작동원리</h4>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/1db57913-9b72-4e4b-95b6-adb7201ca6f1/1F5F6D04-BDFF-4007-B136-038A43F6FC09.jpeg" alt="springboot 작동원리"></p>
<h3 id="q-spring-spring-mvc-spring-boot의-차이점에-대해-각각-설명해-주세요">Q. Spring, Spring MVC, Spring Boot의 차이점에 대해 각각 설명해 주세요.</h3>
<ul>
<li><p>Spring MVC : 규모나 서비스가 어느 정도 있는 애플리케이션은 MVC로 만들어서 WAS로 배포하는게 유리</p>
</li>
<li><p>Spring boot : 내장 톰캣 사용이 가능하여 규모나 서비스가 크지 않은 프로젝트에 적합 </p>
</li>
</ul>
<p>Spring Framework의 생명 주기에 대해서 말해주세요.</p>
<h3 id="q-maven이란">Q. maven이란?</h3>
<p>프로젝트 관리 도구로 가장 많이 사용되는 용도는 프로젝트에 필요한 라이브러리를 자동으로 관리해주는 빌드 도구</p>
<h3 id="q-ioc와-di에-대해서-설명해주세요">Q. IOC와 DI에 대해서 설명해주세요.</h3>
<ul>
<li>IOC (제어의 역전) : 제어의 역전으로 주도권이 스프링에 있다. = 스프링이 다양한 객체들을 읽어서 heap 메모리에 올려준다.</li>
</ul>
<p>🔸 개발자가 직접 원하는 곳에서 new를 이용해 객체 주소를 관리했다면 IoC를 이용해서 스프링이 객체를 스캔하여 메모리에 올리기 때문에 이제는 객체를 개발자가 관리하는 것이 아니라 스프링이 관리해준다.</p>
<ul>
<li><p>DI (의존성 주입) : 스프링이 관리하는 객체들을 어디서든지 가져다가 사용할 수 있게 하는것, 어디서든지 동일한 객체를 사용할 수 있으므로 싱글톤으로 관리가능 </p>
</li>
<li><p>@Component : 클래스 메모리에 로딩</p>
</li>
<li><p>@Autowird : 로딩된 객체를 해당 변수에 넣기</p>
</li>
</ul>
<h3 id="q-aop">Q. AOP</h3>
<p>관점 지향 프로그래밍의 약자로 기존 OOP에서 기능별로 클래스를 분리하였음에도 불구하고 여전히 로그나 트랜잭션, 자원해제, 성능테스트 메서드처럼 공통적으로 반복되는 중복 코드가 발생한다는 단점이 생긴다.
이를 해결할 수 있도록 개발 코드에서는 비즈니스 로직에 집중하고 실행 시 비즈니스 로직의 앞과 두에서 원하는 지점에 해당 공콩 관심사를 수행할 수 있게 하면서 중복 코드를 줄일 수 있는 방식이 바로 이 방식</p>
<p>🔸 클래스는 OOP방식으로, 개발 코드(로그, 트랜잭션, 성능테스트)처럼 반복되는 코드는 AOP방식으로 해서 코드 중복을 줄이자</p>
<h3 id="q-vo-dto-dao에-대해서-각각-설명해-주세요">Q. VO, DTO, DAO에 대해서 각각 설명해 주세요.</h3>
<ul>
<li><p>VO : DTO와 목적이 같지만 차이점은 불변의 성격으로 getter의 기능만</p>
</li>
<li><p>DTO (Data Transfer Object) : 프로세스 간에 데이터 전달 객체, getter, setter 메소드만 포함</p>
</li>
<li><p>DAO (Data Access Object) : 데이터 접근 객체, CRUD 기능 담당</p>
</li>
</ul>
<h3 id="q-servlet이-무엇인가요">Q. Servlet이 무엇인가요?</h3>
<h4 id="서블릿-컨테이너-란">서블릿 컨테이너 란?</h4>
<p>자바코드로 웹을 할 수 있게 컨테이너로 모아놓은 것 ▶ 톰캣</p>
<h4 id="sevlet서블릿">Sevlet(서블릿)</h4>
<p>자바를 사용하여 웹을 만들기 위해 필요한 기술로 클라이언트의 요청을 처리하고, 그 결과를 반환하는 자바 웹 프로그래밍 기술</p>
<p>client request(자바) ▶ 서블릿 컨테이너 ▶
최초요청 시 : 스레드 생성 ▶ 서블릿 객체 생성 ▶ response
재 요청 : 기존에 있는 스레드 재사용</p>
<h4 id="uri-방식">URI 방식</h4>
<ul>
<li>식별자를 통해 접근하는 방식</li>
<li>특정한 파일을 요청할 수 없다.</li>
<li>요청시에는 무조건 자바를 거친다. (무조건 제어권을 톰켓에게 넘긴다.)
ex) <a href="http://naver.com/Picture/a">http://naver.com/Picture/a</a></li>
</ul>
<h3 id="q-dispatcher-servlet이란-무엇인가요">Q. Dispatcher-Servlet이란 무엇인가요?</h3>
<p>Frontcontroller 패턴 : web.xml이 처리해야 할 일이 많기 때문에 특정 주소는 낚아채서 Frontcontroller가 관리하는 것
RequestDispatcher : 웹서버 내부에서 자원을 요청하다보면 톰캣이 새롭게 request/response 해야하는 경우가 생긴다. 그리하여 기존 request/response를 유지하기 위해 나온 것</p>
<p>🔸 DispatcherServlet = Frontcontroller 패턴 + RequestDispatcher </p>
<p>DispatcherServlet이 자동생성될 때 수 많은 객체가 생성(IoC)된다. 보통 필터들이다. 해당 필터들은 내가 직접 등록할 수 도 있고 기본적으로 필요한 필터들을 자동 등록</p>
<p>DispatcherServlet 목적</p>
<ul>
<li>컴포넌트 스캔과 주소분배 인데 주소를 분배하기 위해서는 먼저 IoC해서 모메모리에 객체들을 띄워야 한다.</li>
<li>src 모든 파일 All 스캔</li>
</ul>
<p>컴포넌트 스캔 ▶ IoC 역할을 해준다 ▶ 필요한 것들을 메모리에 올려줌 (어노테이션으로 구분) ▶ 주소분배</p>
<h3 id="q-container란-무엇인가요">Q. Container란 무엇인가요?</h3>
<ul>
<li>인스턴스의 생명주기 관리, 생성된 인스턴스들에게 추가적인 기능 제공</li>
<li>객체의 생성과 소멸을 컨트롤</li>
</ul>
<p>스프링 컨테이너 종류</p>
<ul>
<li><p>빈 팩토리 (BeanFactory)
빈을 생성하고 분배하는 책임을 지는 클래스
빈의 정의는 즉시 로딩하는 반면, 빈 자체가 필요하게 되기 전까지는 인스턴스화 하지 않는다 (Lasy loading)</p>
</li>
<li><p>ApplicationContext
빈팩토리와 유사하지만 좀 더 많은 기능을 제공하는 것
컨텍스트 초기화 시점에서 싱글톤 빈을 미리 로드한 후 애프릴케이션 기동 후에는 빈을 지연없이 얻을 수 있다. bean을 제외한 객체들은 바로 메모리에 로딩</p>
</li>
</ul>
<h3 id="q-bean-이란">Q. Bean 이란?</h3>
<p>스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트
메서드가 객체를 리턴할때 메서드에 @Bean 어노테이션 사용
초기에 메모리에 로드되지 않고 필요할 때 getBean()이라는 메소드를 통해서 호출하여 메모리에 로드 할 수있다. 지금은 getBean()을 사용하지 않고 IoC를 사용하여 DI로 사용한다. ApplicationContext와 다른 점은 Bean Factory에 로드되는 객체들은 미리 로드되지 않고 필요할 때 호출하여 로드돼기 때문에 lasy-loading이 되는 점이다.</p>
<h3 id="q-interceptor와-filter의-차이점을-말해주세요">Q. Interceptor와 Filter의 차이점을 말해주세요.</h3>
<p>Filter : DispatcherServlet의 앞단 정보를 처리
Interceptor : DispatcherServlet에서 controller로 가기전에 정보를 처리한다.</p>
<p>🔸 전역적으로 처리해야하는 로직은 필터로 클라이언트에서 들어오는 디테일한 처리(인증, 권한)에 대해서는 주로 인터셉터에 처리</p>
<h3 id="q-rest-서비스">Q. REST 서비스</h3>
<p>Representational State Transfer 자원을 이름으로 구분하여 정보를 주고 받는 것으로 네트워크 상에서 클라이언트와 서버 사이의 통신 방법 중 하나</p>
<ul>
<li>XML 파일로 된 웹 페이지를 읽어 원하는 정보를 수집하는 기능으로 해당 페이지의 URI만 알면 웹 브라우저로 읽어 정보를 얻을 수 있다.</li>
</ul>
<h3 id="q-mybatis란">Q. MyBatis란?</h3>
<p>객체 지향 언어인 자바의 관계형 데이터베이스 프로그래밍을 보다 쉽게 도와주는 프레임워크</p>
<ul>
<li>개방자가 지정한 SQL 매핑을 지원하는 프레임워크</li>
</ul>
<p>특징</p>
<ul>
<li>SQL문이 코드로부터 완전히 분리<ul>
<li>Mapper파일에 SQL코드를 입력해서 사용</li>
</ul>
</li>
<li>생산성 : 코드가 짧아진다</li>
<li>Spring과의 연동으로 자동화된 처리</li>
<li>유지보수성 향상</li>
</ul>
<p>Controller ▶ Service ▶ DAO ▶ MyBatis ▶ Database</p>
<h3 id="q-jpa란">Q. JPA란?</h3>
<p>JPA (Java Persistence API)로 자바 프로그램을 할때 영구적으로 데이터를 저장하기 위해 필요한 인터페이스</p>
<ul>
<li>JPA는 ORM 기술이다.</li>
<li>반복적인 CRUD 작업을 생략</li>
<li>영속성 context를 가지고 있다.</li>
<li>DB 테이블에 FK를 가지게되면 오브젝트 객체를 가지게 되는데 이러면 DB테이블과 불일치가 일어나는데 이를 ORM을 이용하면 해결 가능</li>
<li>OOP의 관점에서 모델링 가능</li>
<li>방언 처리가 용이하여 Mirgation하기 좋고, 유지보수에 좋다. (= JPA가 처리 할 수 있는 DB 종류가 다양하다.)</li>
</ul>
<h3 id="q-mvc에-대해서-설명해-주세요">Q. MVC에 대해서 설명해 주세요.</h3>
<p>spring MVC는 MVC 패턴 기반의 웹 프레임워크</p>
<ul>
<li>model : 애플리케이션 정보, 데이터 처리관리</li>
<li>view : 사용자 인터페이스(화면) </li>
<li>controller : model과 view 간 상호동작 조정, 사용자의 액션에 응답하는 컴포넌트</li>
</ul>
<p>Spring MVC에서 HTTP 요청이 들어왔을 때의 흐름을 설명해 주세요.</p>
<h3 id="q-spring-security란">Q. Spring security란?</h3>
<p>Spring Security는 Spring 기반의 애플리케이션의 보안(인증과 관한, 인가)를 담당하는 스프링 하위 프레임워크</p>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/8d698a04-80f6-478d-b573-75e9dde37ae3/F79C843E-48BA-4391-9848-46C2269C20A3.jpeg" alt="">
<img src="https://images.velog.io/images/jinjukim-dev/post/c26a911d-be4d-40f3-9f9a-63ffb4edb072/9E7BC73E-348D-4FD6-BF31-A73A8599FACD.jpeg" alt=""></p>
<h4 id="oauth란">OAuth란?</h4>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/534d28c8-f927-47b7-a4df-49ab6e5291ee/45DBAF1F-58BD-400D-9245-103C200C10C6%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8%20-%20%EB%B3%B5%EC%82%AC%EB%B3%B8.jpeg" alt=""></p>
<ul>
<li><strong>code</strong>를 부여 받게 되면 <strong>카카오 인증처리 완료</strong>를 의미</li>
<li><strong>AccessToken</strong>을 부여받게 되면 <strong>권한 부여</strong>를 의미한다<ul>
<li>권한을 부여 받으면 클라이언트 서버는 <strong>자원서버</strong>에 접근하여 사용자의 대한 정보에 접근 할 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="📂-web">📂 Web</h2>
<h3 id="q-servlet">Q. Servlet</h3>
<p>Container가 이해할 수 있게 구성된 순수 자바 코드로 이루어짐</p>
<h3 id="q-get-방식">Q. Get 방식</h3>
<ul>
<li>클라이언트 -&gt; 서버 주소뒤에 이름과 값이 결합된 스트링 형태</li>
<li>위와같은 문제로 보안성이 떨어짐</li>
<li>길이에 제한이 있음</li>
<li>Post 방식보다 전송 속도가 빠름</li>
</ul>
<h3 id="q-post-방식">Q. Post 방식</h3>
<ul>
<li>일정크기 이상 보낼때</li>
<li>인코딩 /  디코딩 작업</li>
<li>속도가 Get 방식보다 느림</li>
<li>Get 방식보다 보안성이 높음</li>
<li>쿼리스트링 데이터 뿐만 아니라 라디오버튼, 텍스트 박스 데이터도 전송 가능</li>
</ul>
<h3 id="q-get-vs-post">Q. Get vs Post</h3>
<table>
<thead>
<tr>
<th>Get</th>
<th>Post</th>
</tr>
</thead>
<tbody><tr>
<td>데이터 요청</td>
<td>데이터 전달</td>
</tr>
<tr>
<td>데이터가 URL에 노출됨</td>
<td>데이터가 노출되지 않음</td>
</tr>
<tr>
<td>길이제한이 있음</td>
<td>길이 제한 없음</td>
</tr>
</tbody></table>
<h3 id="q-session-vs-cookie">Q. Session vs Cookie</h3>
<p>HTTP 프로톨콜은 연결 지향적인 성격이 아니기 때문에 새로운 페이지 요청 시 &quot;새로운 접속&quot;을 하기 때문에 특정 방문자가 머무르고 있는 동안 그 방문자의 상태를 지속 시키기위해 사용한다.</p>
<h3 id="q-session">Q. Session</h3>
<ul>
<li>관련 데이터를 server에 저장 -&gt; 모든 정보를 서버에 저장하면 서버가 느려질 수 있는 단점</li>
<li>웹브라우저 캐시에 저장되어 브라우저를 닫거나 서버 삭제 시 사라짐</li>
<li>쿠키에 비해 보안성이 좋다.</li>
</ul>
<h3 id="q-cookie">Q. Cookie</h3>
<ul>
<li>관련 데이터를 클라이언트에 텍스트 파일로 저장 -&gt; 클라이언트 pc에 저장함</li>
<li>다른 사용자로 부터 임의 변경이 가능하여 보안성이 낮다.</li>
</ul>
<h3 id="q-tcp-vs-udp">Q. TCP VS UDP</h3>
<ul>
<li>TCP (transmission control protocol)</li>
<li>UDP (user datagram protocol)</li>
</ul>
<table>
<thead>
<tr>
<th>TCP</th>
<th>UDP</th>
</tr>
</thead>
<tbody><tr>
<td>연결형 서비스 제공</td>
<td>비연결형 서비스 제공</td>
</tr>
<tr>
<td>높은 신뢰성 보장</td>
<td>신회성이 낮음</td>
</tr>
<tr>
<td>연결 설정 - 3way handshaking 연결 해제 - 4way handshaking</td>
<td>데이터 수신 여부 확인 X</td>
</tr>
<tr>
<td>데이터 흐름제어, 혼잡제어</td>
<td>데이터 전송 순서가 바뀔수 있음</td>
</tr>
<tr>
<td>양방향성 서비스 제공</td>
<td></td>
</tr>
</tbody></table>
<h3 id="q-형상관리">Q. 형상관리</h3>
<p>정보화 프로젝트 및 유지보수의 효율적인 협업을 위한 버전관리
ex) cvs, svn, Git</p>
<h3 id="q-include">Q. include</h3>
<p>정적 include : jsp가 컴파일 되기 전에 include한 파일이 부모페이지에 삽입되어 컴파일</p>
<ul>
<li>삽입후 -&gt; 컴파일</li>
</ul>
<p>동적 include : 사용자가 부모페이지 호출 시, 실행되어질 시점에 include파일 삽입</p>
<ul>
<li>호출 되는 시점에서 삽입</li>
</ul>
<h3 id="q-library">Q. Library</h3>
<ul>
<li>독립성을 가진 최소단위의 기능 (메서드 단위)</li>
<li>재사용 가능한 최소 단위 기능 또는 기능들의 집합</li>
<li>기능을 사용하기 위해 다은 기능이 필요하지 않음</li>
<li>재사용 할 수있는 함수 제공 = 라이브러리</li>
</ul>
<h2 id="📂-java">📂 java</h2>
<h3 id="q-java란">Q. Java란?</h3>
<p>네트워크상에서 쓸 수 있도록 미국의 선 마이크로 시스템즈가 개발한 객체 지향프로그래밍 언어</p>
<h3 id="q-java-특징">Q. Java 특징</h3>
<ul>
<li>JVM만 설치하면 컴퓨터의 운영체제에 상관업시 작동 - 운영체제에 독립적</li>
<li>기본 자료형을 제외한 모든 요소들이 객체로 표현</li>
<li>캡슐화, 상속, 다형성</li>
<li>Garbage Collector 통한 자동적인 메모리 관리</li>
<li>멀티쓰레드 지원</li>
</ul>
<h3 id="자료형">자료형</h3>
<h3 id="q-static정적">Q. static(정적)</h3>
<p>클래스가 로딩될때, 메모리 공강을 할당하는데 처음 설정된 메모리 공간이 변하지 않음. 어디서나 속성과 메서드 공유 가능</p>
<h3 id="q-지역변수-vs-전역변수">Q. 지역변수 vs 전역변수</h3>
<table>
<thead>
<tr>
<th>지역변수</th>
<th>전역변수</th>
</tr>
</thead>
<tbody><tr>
<td>해당 함수 내에서만 사용가능</td>
<td>모든 함수에서 사용가능</td>
</tr>
<tr>
<td>함수를 벗어나면 자동 소멸</td>
<td>프로그램 종료시 소멸</td>
</tr>
</tbody></table>
<h3 id="q-primary-type">Q. Primary type</h3>
<p>변수에 값 자체를 저장</p>
<ul>
<li>정수형 : byte, short, int, long</li>
<li>실수형 : float, double</li>
<li>문자형 : char</li>
<li>논리형 : boolean</li>
</ul>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/2b715ae6-4c85-4429-a6cc-f9b1d19693ad/image.png" alt=""></p>
<h3 id="q-reference-type">Q. Reference type</h3>
<p>메모리상에 객체가 있는 위치(주소)를 저장</p>
<ul>
<li>class, Interface, Array</li>
</ul>
<h3 id="q-wrapper-class">Q. Wrapper class</h3>
<p>primitive type 간단한 데이터를 객체로 만들어야 할 경우</p>
<ul>
<li>int ▶ Integer</li>
</ul>
<h3 id="q-char-type과-string-type으로-나뉘어져-있는-이유는-무엇인가요">Q. char type과 string type으로 나뉘어져 있는 이유는 무엇인가요?</h3>
<p>char </p>
<ul>
<li>기본 유형<ul>
<li>해당 변수안에 직접적으로 값을 가지고 있다</li>
<li>해당 값이 있는 좌표를 가지지 않음</li>
</ul>
</li>
<li>한 문자 (글자수 제한)</li>
</ul>
<p>String </p>
<ul>
<li>클래스타입의 변수<ul>
<li>해당 값이 위치한 좌표를 내용물로 가진다.</li>
</ul>
</li>
<li>0개 이상의 문자 (글자수 제한이 없다)</li>
</ul>
<p>🔸 == 연산자를 사용해보면 char의 경우 값이 같다면 ==을 사용할 수 있지만 String의 경우 내용이 같더라도 서로 다른 좌표(주소)가 생성되기 때문에 ==으로 비교시 다른값으로 나온다. <strong>그래서</strong> string은 <strong>.equals()</strong>메소드로 내용물을 비교하여야 한다.</p>
<h3 id="q-문자열을-리터럴string--abcd로-할당하는-것과-객체string--new-stringabcd로-할당하는-방식의-차이가-무엇인가요">Q. 문자열을 리터럴(string = &quot;abcd&quot;)로 할당하는 것과 객체(string = new String(&quot;abcd&quot;))로 할당하는 방식의 차이가 무엇인가요?</h3>
<p>객체 할당 방식은 heap영역에서 할당되고, 리터럴 방식을 String Constant Pool이라는 영역에 할당</p>
<p>equals()로 비교하면 같은 값이지만 == 연산자로 비교 시 주소가 달라 다른 값으로 나온다</p>
<h3 id="jvm">JVM</h3>
<p>JVM (Java Virtual Machine)은 운영체제에서 할당받은 메모리 영역(Runtime Data Area)</p>
<ul>
<li>메소드 영역(Method Area)</li>
<li>스레드 영역(Thread Area) ▶ 영역마다 하나의 JVM 스택 영역으로 존재</li>
<li>힙 영역(Heap Area)</li>
</ul>
<h4 id="q-jvm의-구조에-대해서-설명해-주세요">Q. JVM의 구조에 대해서 설명해 주세요.</h4>
<p><img src="https://images.velog.io/images/jinjukim-dev/post/4a408cbb-8e3f-4a6f-950b-4c3da776b219/image.png" alt=""></p>
<p>메소드 영역 (Method Area)</p>
<ul>
<li>static 변수, 전역변수, 코드에서 사용되는 Class정보</li>
<li>JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역</li>
</ul>
<p>힙 영역(Heap Area)</p>
<ul>
<li>객체오 배열이 생성되는 영역 </li>
<li>GC에 의해 메모리가 관리됨</li>
</ul>
<p>JVM Stack Area (Thread Area)</p>
<ul>
<li>지역변수, 함수(메서드)등이 할당되는 LIFO 방식</li>
<li>배열의 경우 배열의 변수는 스택영역에 생성, 배열 데이터 자체는 Heap영역에 생성</li>
</ul>
<h3 id="q-object-oriented-programming-객체-지향">Q. Object-Oriented Programming (객체 지향)</h3>
<p>객체지향 프로그래밍 객체와 객체의 상호작용을 통해 프로그램이 동작</p>
<p>객체 지향 프로그래밍은 OOP(Object Oriented Programming)이라고도 한다.
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.</p>
<p>객체지향 특징</p>
<ul>
<li><p>추상화
불필요한 정보는 숨기고 필요한 정보만을 표현함으로써 공통의 속성이나 기능을 묶어 이름을 붙이는 것 
(여러개의 클래스에서 공통적인 요소, 필수적인 요소를담은 추상클래스)</p>
</li>
<li><p>캡슐화 
속성과 기능을 정의하는 멤버 변수와 메소드를 클래스라는 캡슐에 넣은 것이다. 즉, 관련된 기능(메소드)과 속성(변수)을 한 곳에 모으고 분류하기 때문에 재활용이 원활하다.
목적 : 코드를 수정없이 재활용하는 것, 정보 은닉, setter와 getter로 접근</p>
</li>
<li><p>상속
부모 클래스의 속성과 기능을 그대로 이어 받아 사용할 수 있게 하고 기능의 일부분을 변경해야 할 경우, 상속받은 자식 클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것이다.
상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스 정의 가능, 코드를 공통적으로 관리하여 코드 추가 및 변경이 용이</p>
</li>
<li><p>다형성
하나의 변수명, 함수명 등이 상황에 따라서 다른 의미로 해설될 수 있는 것이다. 상속을 통해 기능 확장 / 변경 할 수 있게 하는 것
즉, 오버라이딩, 오버로딩이 가능</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td>코드재사용성이 높다</td>
<td>처리 속도가 상대적으로 느림</td>
</tr>
<tr>
<td>코드의 변경 용이</td>
<td>객체가 많으면 용량이 커질 수 있음</td>
</tr>
<tr>
<td>직관적인 코드분석</td>
<td></td>
</tr>
<tr>
<td>개발속도 향상</td>
<td>설계 시 많은 노력과 시간 필요</td>
</tr>
<tr>
<td>상속을 통한 장점</td>
<td></td>
</tr>
</tbody></table>
<h3 id="q-객체지향-언어-vs-절차지향-언어">Q. 객체지향 언어 vs 절차지향 언어</h3>
<p>객체지향 언어</p>
<ul>
<li>객체가 중심이 되어 코드작성하여 객체에 기능을 정의하고 호출순서는 객체가 담당</li>
<li>절차지향 언어, 유지보수 보안하며 객체라는 독립된 작은 단위로 모든 데이터와 절차 처리<ul>
<li>ex) java, python</li>
</ul>
</li>
</ul>
<p>절차지향 언어</p>
<ul>
<li>절차 중심으로 작성하는 코드 방식으로 순차적인 처리를 중시하는 언어</li>
<li>객체를 서로 절차적인 관계로 묶어 프로그램 작성<ul>
<li>ex) c</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th>객체지향 언어</th>
<th>절자지향 언어</th>
</tr>
</thead>
<tbody><tr>
<td>코드가 간단하여 프로그램 개발이 빠르다</td>
<td>컴퓨터 적업 처리 방식과 유사</td>
</tr>
<tr>
<td>기존코드 재사용</td>
<td>처리가 빠름</td>
</tr>
<tr>
<td>유지보수가 쉽다</td>
<td>효율적인 일처리 가능</td>
</tr>
<tr>
<td>처리속도가 느려질수 있다</td>
<td>프로그램 개발이 번거로움</td>
</tr>
<tr>
<td></td>
<td>코드가 많아 유지보수가 힘듦</td>
</tr>
</tbody></table>
<h3 id="q-object-객체">Q. Object (객체)</h3>
<p>객체는 OOP에서 데이터(변수), 데이터에 관련되는 동작(함수), 절차, 방법, 기능을 모두 포함하는 개념으로 모든 클래스의 최상위는 Object가 있다.</p>
<h3 id="q-객체-생성">Q. 객체 생성</h3>
<p>클래스로부터 &quot;new&quot;를 이용해서 객체를 생성
ex) Grandeur myCar1 = new Grandeur();</p>
<ul>
<li>Grandeur 클래스로부터 myCar1이라는 객체 생성</li>
</ul>
<h3 id="q-class">Q. Class</h3>
<p>멤버 변수(속성), 메서드(기능), 생성자등으로 구성으로 클래스도 하나의 데이터 타입(자료형)</p>
<h3 id="q-생성자">Q. 생성자</h3>
<p>클래스 이름과 동일한 메서드</p>
<p>목적</p>
<ul>
<li>인스턴스 생성시 필드에 초기값 부여</li>
<li>초기화 명령 실행</li>
</ul>
<p>특징</p>
<ul>
<li>반환형 x</li>
<li>가장 먼저 호출되어 메모리에 객체가 올라감</li>
<li>생성자에서 바로 값을 받을 수 있다. (매개변수)</li>
</ul>
<h3 id="q-멤버-변수">Q. 멤버 변수</h3>
<p>자료형 + 데이터형 + 변수이름
ex) public String color;</p>
<h3 id="q-parameter매개변수">Q. Parameter(매개변수)</h3>
<p>메서드를 호출할때 데이터를 전달 할 수 있다.</p>
<h3 id="q-this">Q. this</h3>
<p>현 객체를 가리키는 것 this.변수명 = 전역변수</p>
<ul>
<li>메소드에 있는 지역변수를 전역변수에 담을때 사용</li>
<li>객체가 던져준 변수를 객체가 소멸될때 까지 사용하기 위함 지역변수 -&gt; 전역변수</li>
</ul>
<h3 id="q-super">Q. super</h3>
<p>상위클래스에 변수를 말함
ex) 지점클래스가 본사클래스를 상속받고 있는 경우
this.openYear = 2000; (현재 클래스 개업년도)
super.openYear = 1995; (상속받는 클래스 개업년도)</p>
<h3 id="q-final">Q. final</h3>
<p>변수</p>
<ul>
<li>변수가 Final로 선언되면 변수의 값 변경 X
메소드</li>
<li>Final 메소드는 오버라이드 X
클래스</li>
<li>상속 X
생성자</li>
<li>생성자는 Final 될 수 없다.</li>
</ul>
<h3 id="q-추상화-vs-인스턴스">Q. 추상화 vs 인스턴스</h3>
<p>클래스 ▶ 객체 (인스턴스화) : 클래스로부터 새로운 객체를 생성하는 행위
객체, 객체 ▶ 클래스 (추상화) : 객체들을 추상화하여 그들의 공통적인 속성을 기술하는 것</p>
<h3 id="q-interface">Q. Interface</h3>
<p>클래스와 달리 캑체 생성을 x, 클래스에서 구현해야 하는 작업명세서</p>
<ul>
<li>추상 메서드, 상수만을 멤버로 하며 메소드는 선언만 가능하며 정의 할 수 없음</li>
<li>Implements 키워드 사용</li>
<li>자바는 단일 상속이 원칙이지만 인터페이스는 다중 상속 가능</li>
</ul>
<h4 id="q-본인-관점에서-인터페이스는-주로-어떨-때-사용하나요">Q. 본인 관점에서, 인터페이스는 주로 어떨 때 사용하나요?</h4>
<ul>
<li>구성하는 요소들이 자주 바뀔때 쓰면 유용</li>
<li>메소드 형태만 서로 공유하기 떄문에 재정의되는 상활일 때도 사용 적합</li>
<li>협업, 다중 상속을 위해 사용</li>
</ul>
<h4 id="q-함수형-인터페이스란-무엇인가요">Q. 함수형 인터페이스란 무엇인가요?</h4>
<p>1개의 추상 메소드를 갖고 있는 인터페이스를 말한다.
Single Absttract Method(SAM)이라고 불리기도 함
목적</p>
<ul>
<li>람다식으로 만든 객체에 접근하기 위함</li>
</ul>
<h3 id="q-abstract-class-추상클래스">Q. abstract class (추상클래스)</h3>
<p>클래스의 공통된 부분을 뽑아서 별도의 클래스로 만들어 놓고, 상속해서 사용</p>
<ul>
<li>멤버변수 사용</li>
<li>생성자 </li>
<li>extends 키워드 사용</li>
<li>abstract 메서드는 상속받은 클래스에서 반드시 구현</li>
<li>일반 메서드도 가질 수 있다 (class의 특징도 가진다)</li>
</ul>
<h3 id="q-interface-vs-abstract-class">Q. Interface vs abstract class</h3>
<table>
<thead>
<tr>
<th>공통점</th>
<th>Interface</th>
<th>abstract class</th>
</tr>
</thead>
<tbody><tr>
<td>추상메서드를 가진다</td>
<td>상수, 추상메서드만 가능</td>
<td>클래스 속성으로 메서드, 추상메서드 모두 ok</td>
</tr>
<tr>
<td>객체 생성이 불가하며 자료형으로 사용됨</td>
<td>추상 메서드 선언만 가능</td>
<td>선언도, 구현도 모두 ok</td>
</tr>
<tr>
<td>사용하기 위해서는 하위클래스에서 확장 구현해야함</td>
<td>다중상속 가능</td>
<td>단일상속만 가능</td>
</tr>
</tbody></table>
<h3 id="q-클래스-객체-인스턴스-차이에-대해서-설명">Q. 클래스, 객체, 인스턴스 차이에 대해서 설명</h3>
<p>클래스</p>
<ul>
<li>객체를 만들어 내기 위한 설계도, 연관있는 변수와 메서드 집합</li>
</ul>
<p>객체</p>
<ul>
<li>구현할 대상, 클래스에 선언된 모양 그대로 실체 (클래스 인스턴스)</li>
</ul>
<p>인스턴스</p>
<ul>
<li>설계도 바탕을 구현된 실체, 실체화된 인스턴스는 메모리에 할당</li>
</ul>
<h3 id="q-thread쓰레드">Q. Thread(쓰레드)</h3>
<p>프로세스 내에서 동시에 실행되는 독립적인 실행 단위</p>
<table>
<thead>
<tr>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td>빠른 프로세스 생성</td>
<td>교착상태에 빠질 수 있다</td>
</tr>
<tr>
<td>적은 메모리 사용</td>
<td></td>
</tr>
<tr>
<td>쉬운 정보 공유</td>
<td></td>
</tr>
</tbody></table>
<h3 id="q-process프로세스">Q. Process(프로세스)</h3>
<p>운영체제에서 실행중인 하나의 프로그램</p>
<ul>
<li>process &gt; thread</li>
<li>여러개의 스레드 = 하나의 프로세스</li>
</ul>
<h3 id="q-overloading">Q. Overloading</h3>
<p>같은 이름의 메소드를 여러개 정의하는 것으로 데이터 타입 or 매개변수가 달라야한다.</p>
<ul>
<li>같은 이름으로 메소드를 사용하지만 다른 용도로 사용되며, 그 결과물도 다르게 이용하기 위함</li>
</ul>
<h3 id="q-overriding">Q. Overriding</h3>
<p>상속에서 나온 개념으로 상위클래스의 메소드를 하위클래스에서 재정의</p>
<h3 id="q-접근제한자">Q. 접근제한자</h3>
<ul>
<li>public : 제한이 없음(같은 프로젝트 내에 어디서든 사용가능)</li>
<li>protected : 같은 pakage 내, 다른 pakage에서 상속받아 하위에서 접근 가능</li>
<li>default : 같은 pakage에서만 접근 가능</li>
<li>private : 같은 class내에서만 접근 가능</li>
</ul>
<h3 id="q-garbage-collector">Q. Garbage collector</h3>
<p>시스템에서 더이상 사용하지 않는 동적 할당된 메모리 블럭(연결이 끊긴 배열)을 찾아 자동으로 다시 사용가능한 자원으로 회수</p>
<ul>
<li>사용하지 않는 메모리를 자동으로 사용 가능한 자원으로 회수</li>
</ul>
<h3 id="q-equals와-의-차이는-무엇인가요">Q. equals와 ==의 차이는 무엇인가요?</h3>
<p>equals() 메소드는 대상의 내용 자체를 비교
== 연산자는 대상의 주소값을 비교</p>
<p>a (주소: 500, 값: &quot;aaa&quot;)
b (주소: 600, 값: &quot;aaa&quot;)</p>
<p>a.equals(b) : true
a == b : false</p>
<h4 id="q-hashcode란-무엇인가요">Q. hashCode란 무엇인가요?</h4>
<p>자바에서 동일한 이름의 객체가 여러개 생성될 수 있는데 이 객체들은 이름만 같을 뿐 서로 다른 상태를 가진 객체들이 되는 것이다.
이런 객체를 구별하기 위해, 고유한 정수값으로 출력시켜주는 메소드가 hashCode()</p>
<h3 id="q-java는-call-by-value일까요-call-by-reference-일까요">Q. Java는 Call By Value일까요, Call By Reference 일까요?</h3>
<ul>
<li>Call by Value : 값에 대한 호출</li>
<li>Call by Reference : 참조에 대한 호출</li>
</ul>
<h3 id="q-java의-collection에-대해서-설명해-주세요">Q. Java의 Collection에 대해서 설명해 주세요.</h3>
<p>List</p>
<ul>
<li>삽입 순서 OK</li>
<li>중복 OK</li>
<li>ex) ArrayList, LinkedList<ul>
<li>ArrayList 가변형 배열 메모리 위치가 쭉 이어짐 -&gt; 검색에 빠름(조회에 유리)</li>
<li>Linked List 배열인데 모메로 위치가 뒤죽박죽 -&gt; 삭제 시 빠름(삽입, 삭제 유리)</li>
</ul>
</li>
</ul>
<p>Set</p>
<ul>
<li>중복 X</li>
<li>인덱스를 사용하지 않으므로 저장순서가 보장 되지 않음-&gt; 순서 X</li>
</ul>
<p>Map</p>
<ul>
<li>key, value </li>
<li>key 중복 X, value 중복 OK</li>
</ul>
<h4 id="q-array와-arraylist의-차이점은-무엇인가요">Q. Array와 ArrayList의 차이점은 무엇인가요?</h4>
<p>Array는 길이가 정해져있는 배열
ArrayList 가변형 배열 메모리 위치가 쭉 이어짐 -&gt; 검색에 빠름(조회에 유리)
Linked List 배열인데 모메로 위치가 뒤죽박죽 -&gt; 삭제 시 빠름(삽입, 삭제 유리)</p>
<h3 id="q-lambda람다란">Q. Lambda(람다)란?</h3>
<blockquote>
<p>람다 함수는 프로그래밍 언어에서 사용되는 개념으로 익명 함수를 지칭하는 용어</p>
</blockquote>
<p>람다의 특징</p>
<ul>
<li>이름을 가질 필요가 없다. (익명 함수)</li>
</ul>
<p>람다의 장단점</p>
<table>
<thead>
<tr>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td>코드의 간결성</td>
<td>호출이 까다롭다</td>
</tr>
<tr>
<td>지연연산 수행</td>
<td>람다 사용시 단순 for, while 성능이 떨어짐</td>
</tr>
<tr>
<td>병렬처리 가능(멀티쓰레드 사용)</td>
<td>불필요하게 사용시 가독성이 떨이짐</td>
</tr>
</tbody></table>
<h3 id="q-java-generic에-대해서-설명해-주세요">Q. Java Generic에 대해서 설명해 주세요.</h3>
<p>Genric은 일반적인 이라는 뜻을 가진 단어로 클래스 내웁에서 사용할 데이터 타입을 외부에서 지정하는 방법</p>
<p>목적</p>
<ul>
<li>타입 에러 사전 방지</li>
<li>타입 변환 제거(캐스팅)</li>
</ul>
<p>프로그래밍의 Generic</p>
<ul>
<li>일반적인 코드를 작성하고, 이 코드를 다양한 타입의 객체에 대하여 재사용</li>
<li>클래스에서 사용할 타입을 클래스 외부에서 설정하는 타입</li>
<li>Java 1.5부터 추가</li>
</ul>
<h3 id="q-iterator와-iterable-차이는-무엇인가요">Q. iterator와 iterable 차이는 무엇인가요?</h3>
<p>iterator</p>
<ul>
<li>컬렉션 프레임워크에서 저장된 요소를 읽어오는 방법을 표준화하기 위한 역할(인터페이스)</li>
<li>List, Set</li>
<li>주로 읽기 전용으로 사용</li>
</ul>
<p>iterable</p>
<ul>
<li>순회할 수 있는 컬렉션</li>
<li>iterable 인터페이스를 implement하면 객체는 foreach문을 사용할 수 있음</li>
</ul>
<h4 id="q-foreach를-사용할-수-있는-자료구조는-어떤-인터페이스를-상속받고-있나요">Q. foreach를 사용할 수 있는 자료구조는 어떤 인터페이스를 상속받고 있나요?</h4>
<p>Iterable 인터페이스를 구현</p>
<h3 id="q-synchronized-키워드에-대해-설명해-주세요">Q. synchronized 키워드에 대해 설명해 주세요.</h3>
<p>동기화란 하나의 자원(데이터)에 대해서 여러 스레드가 사용하려고 할 때 한 시점에서 하나의 스레드만 사용할 수 있도록 하는 것</p>
<h3 id="q-ddl-dml-dcl에-대해-설명">Q. DDL, DML, DCL에 대해 설명</h3>
<ul>
<li>DDL (Data Define Language) 테이블/뷰/인덱스 정의/변경/제거 할때 사용<ul>
<li>테이블 생성, 테이블 내용 변경, 테이블 삭제</li>
<li>ex) CREATE, ALTER, DROP</li>
</ul>
</li>
<li>DML (Data Manipulation Language) 질의를 통해서 저장된 데이터 실질적으로 관리<ul>
<li>테이블 안의 데이터 하나한를 추가하고 삭제, 수정</li>
<li>ex) INSERT, DELETE, UPDATE</li>
</ul>
</li>
<li>DCL (Data Control Language) 보안/무결성/회복/병행 제어등을 정의<ul>
<li>ex) COMMIT, ROLLBACK, GRANT, REVOKE</li>
</ul>
</li>
</ul>
<h3 id="q-json">Q. json</h3>
<p>JSON은 경량의 DATA-교환방식
Javascript에서 객체를 만들 때 사용하는 표현식을 의미</p>
<ul>
<li>JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 적어서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용</li>
<li>특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링할 수 있는 라이브러리를 제공한다.</li>
</ul>
<h4 id="xml">XML</h4>
<ul>
<li>HTML과 매우 비슷한 문자 기반의 마크업 언어</li>
</ul>
<h3 id="q-리플렉션reflection이란-무엇인가요">Q. 리플렉션(Reflection)이란 무엇인가요?</h3>
<p>객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법으로 스프링 컨테이너에서 BeanFactory의 경우 객체가 호출될때 인스턴스를 생성하게 되는데 이때 필요한 기술이다.</p>
<h3 id="q-직렬화serialization과-역직렬화deserialization에-대해서-설명해-주세요">Q. 직렬화(Serialization)과 역직렬화(Deserialization)에 대해서 설명해 주세요.</h3>
<p>직렬화</p>
<ul>
<li>객체를 직렬화하여 전송 가능한 형태로 만드는 것을 의미(객체 ▶ 전송가능 형태)</li>
<li>객체들의 데이터를 연속적인 데이터로 변형하여 Stream을 통해 데이터를 읽도록 해준다.</li>
<li>주로 객체들을 통째로 파일로 저장하거나 전송하고 싶을 때 주로 사용</li>
<li>implements Serializable</li>
</ul>
<p>역직렬화</p>
<ul>
<li>역으로 직렬화하여 다시 객체의 형태로 만드는 것을 의미(전송가능 형태 ▶ 객체)</li>
<li>저장된 파일을 읽거나 전송된 Stream 데이터를 읽어 원래 객체의 형태로 복원</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>