<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>porco&apos;s chips</title>
    <description></description>
    <link>https://porcochips.github.io/</link>
    <atom:link href="https://porcochips.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 28 Apr 2026 11:12:17 +0900</pubDate>
    <lastBuildDate>Tue, 28 Apr 2026 11:12:17 +0900</lastBuildDate>
    <generator>Jekyll v4.1.1</generator>


    

    
      <item>
        <title>ROOT</title>
        <description></description>
        <pubDate>Sun, 25 Jul 2021 18:00:13 +0900</pubDate>
        <link>https://porcochips.github.io/wiki/index/</link>
        <guid isPermaLink="true">https://porcochips.github.io/wiki/index/</guid>
        
        
      </item>
    

    
      <item>
        <title>MathJax로 LaTeX 사용하기</title>
        <description></description>
        <pubDate>Mon, 04 Nov 2019 22:13:47 +0900</pubDate>
        <link>https://porcochips.github.io/wiki/mathjax-latex/</link>
        <guid isPermaLink="true">https://porcochips.github.io/wiki/mathjax-latex/</guid>
        
        <category>latex</category>
        
        
      </item>
    

    
      <item>
        <title>HOW TO</title>
        <description></description>
        <pubDate>Sun, 04 Feb 2018 15:57:05 +0900</pubDate>
        <link>https://porcochips.github.io/wiki/how-to/</link>
        <guid isPermaLink="true">https://porcochips.github.io/wiki/how-to/</guid>
        
        <category>how-to</category>
        
        
      </item>
    


      <item>
        <title>hello</title>
        <description>&lt;p&gt;첫 번째 포스트입니다.&lt;/p&gt;
</description>
        <pubDate>Sun, 26 Apr 2026 10:00:00 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2026/04/26/hello/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2026/04/26/hello/</guid>
        
        
      </item>

      <item>
        <title>Next JWP Study 16</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-여섯-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-여섯-번째-수업-이모저모&quot;&gt;열 여섯 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#마지막-말씀&quot; id=&quot;markdown-toc-마지막-말씀&quot;&gt;마지막 말씀&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#교수님이-과거로-돌아가-자바-웹-백엔드-개발자를-시작한다면&quot; id=&quot;markdown-toc-교수님이-과거로-돌아가-자바-웹-백엔드-개발자를-시작한다면&quot;&gt;교수님이 과거로 돌아가 자바 웹 백엔드 개발자를 시작한다면&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#효과적으로-학습하는-방법론도-공부할-것&quot; id=&quot;markdown-toc-효과적으로-학습하는-방법론도-공부할-것&quot;&gt;효과적으로 학습하는 방법론도 공부할 것&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#자바-웹-개발-관련-추천-서적&quot; id=&quot;markdown-toc-자바-웹-개발-관련-추천-서적&quot;&gt;자바 웹 개발 관련 추천 서적&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;열-여섯-번째-수업-이모저모&quot;&gt;열 여섯 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-06-01 19:00:03 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;오늘은 8주 과정의 마지막 수업.&lt;/li&gt;
  &lt;li&gt;수업 시작시에 화재 경보가 울림.
    &lt;ul&gt;
      &lt;li&gt;대피를 주저하는 사람들도 있었지만 결국 모두 안전하게 건물 바깥으로 빠져나갔다.&lt;/li&gt;
      &lt;li&gt;원칙에 충실한 회사를 다닌다는 것이 기쁘다.&lt;/li&gt;
      &lt;li&gt;다행히 진짜 화재가 아니었으므로(경보기 오작동), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19:35&lt;/code&gt;에 강의실로 복귀하여 수업을 계속 들을 수 있었다.&lt;/li&gt;
      &lt;li&gt;화재 경보에 대한 안전 불감증도 일종의 &apos;깨진 창문&apos;으로 볼 수 있지 않을까?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;마지막-말씀&quot;&gt;마지막 말씀&lt;/h1&gt;

&lt;h2 id=&quot;교수님이-과거로-돌아가-자바-웹-백엔드-개발자를-시작한다면&quot;&gt;교수님이 과거로 돌아가 자바 웹 백엔드 개발자를 시작한다면&lt;/h2&gt;

&lt;p&gt;시작하는 단계&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;기본: Spring Boot + Spring&lt;/li&gt;
  &lt;li&gt;DB: Spring Data JPA, ORM 프레임워크, 관계형 DB, DB Migration 도구
    &lt;ul&gt;
      &lt;li&gt;ORM은 현재 프로젝트에 사용하지 않더라도 미래를 위해…&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;인증, 인가: Spring Security&lt;/li&gt;
  &lt;li&gt;Clean code: 객체지향, 테스트, 리팩토링&lt;/li&gt;
  &lt;li&gt;빌드 도구: 메이븐 또는 그래들&lt;/li&gt;
  &lt;li&gt;Logging: SLF4J, Logback&lt;/li&gt;
  &lt;li&gt;자동화: 쉘 스크립트&lt;/li&gt;
  &lt;li&gt;소스 코드 관리: Git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;한 단계 더 나아간다면&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;프레임워크, 라이브러리 직접 구현&lt;/li&gt;
  &lt;li&gt;기초 지식: 네트워크, HTTP&lt;/li&gt;
  &lt;li&gt;DB: No SQL&lt;/li&gt;
  &lt;li&gt;Restful API, react.js, angular.js&lt;/li&gt;
  &lt;li&gt;함수형 프로그래밍, Reactive Programming&lt;/li&gt;
  &lt;li&gt;보안과 성능: Cache(서버측 Cache, 정적인 자원 Cache), Message Queue, SSL&lt;/li&gt;
  &lt;li&gt;자동화: Ansible, Docker&lt;/li&gt;
  &lt;li&gt;개발문화 및 프로세스&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;효과적으로-학습하는-방법론도-공부할-것&quot;&gt;효과적으로 학습하는 방법론도 공부할 것&lt;/h2&gt;

&lt;p&gt;추천 서적&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?barcode=9788901150598&quot;&gt;습관의 힘&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788995540213&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;이너 게임: 배우며 즐겁게 일하는 법(절판)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788973378869&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;몰입의 즐거움&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9791186805282&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;1만 시간의 재발견: 노력은 왜 우리를 배신하는가&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;자바-웹-개발-관련-추천-서적&quot;&gt;자바 웹 개발 관련 추천 서적&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788965400677&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;자바 웹 개발 워크북&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788966261161&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;Effective Java&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960773431&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;토비의 SPRING&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;JPA 프로그래밍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788966261024&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;TDD by example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788979149715&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;Refactoring&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788998139766&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;객체지향의 사실과 오해&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788969090010&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;객체 지향과 디자인 패턴&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788966260959&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;Clean Code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788992939850&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;도메인 주도 설계&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052&quot;&gt;Working Effectively with Legacy Code 1st Edition&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788989975922&amp;amp;orderClick=LAH&amp;amp;Kc=&quot;&gt;레거시 코드 활용 전략&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Isolation level에 대해서는 SQL 92 문서를 참고 (Table9, 69쪽)
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt&quot;&gt;SQL 92&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-KlMu_0pZySnFa_fxo_n&quot;&gt;Test, OOP 피드백&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-Kiheahir0nyud31unoI&quot;&gt;Spring Profile 및 서버 배포&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://blog.restcase.com/rest-api-error-codes-101/&quot;&gt;REST API Error Codes 101&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-spring-boot/tree/step12-spring-profile&quot;&gt;참고용 교수님 저장소&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;DB migration 도구
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://flywaydb.org/&quot;&gt;flywaydb&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://www.liquibase.org/&quot;&gt;liquibase&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://firebasestorage.googleapis.com/v0/b/nextstep-real.appspot.com/o/lesson-attachments%2F-KgqHzXq92AfQVxeZor5%2F8-2-3.%20%EC%B5%9C%EC%A2%85%20%EC%A0%95%EB%A6%AC.pdf?alt=media&amp;amp;token=893d17ee-b6fc-4927-bed7-f973c55abb09&quot;&gt;최종 정리.pdf&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-book/tree/master/chapter1&quot;&gt;초보 웹 개발자를 위하여&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3mgMwObtaQ0&quot;&gt;자바 웹 개발자의 학습 로드맵&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://slipp.net/&quot;&gt;교수님께 질문&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 01 Jun 2017 19:52:40 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/06/01/jwp-16/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/06/01/jwp-16/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 15</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-다섯-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-다섯-번째-수업-이모저모&quot;&gt;열 다섯 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#restful-api-설계&quot; id=&quot;markdown-toc-restful-api-설계&quot;&gt;Restful API 설계&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;열-다섯-번째-수업-이모저모&quot;&gt;열 다섯 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-29 19:00:01 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;책 추천: &lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788931004090&amp;amp;orderClick=JAj&quot;&gt;내가 믿는 세상 by E.F. 슈마허&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;오늘은 Restful API 설계 실습을 해본다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;restful-api-설계&quot;&gt;Restful API 설계&lt;/h1&gt;

&lt;p&gt;교수님 추천 읽어볼만한 글들&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api&quot;&gt;Best Practices for Designing a Pragmatic RESTful API&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pages.apigee.com/rs/apigee/images/api-design-ebook-2012-03.pdf&quot;&gt;PDF: Web API Design Crafting Interfaces that Developers Love&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/articles/richardsonMaturityModel.html&quot;&gt;Martin Fowler - steps toward the glory of REST&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;REST를 처음 제안한 로이 필딩의 논문 링크. 다 읽기 번거롭다면 &lt;strong&gt;CHAPTER 5: Representational State Transfer (REST)&lt;/strong&gt;라도 읽어두면 괜찮다.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm&quot;&gt;Architectural Styles and the Design of Network-based Software Architectures by Roy Thomas Fielding&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.google.co.kr/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=2&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0ahUKEwjVj5Hj-JTUAhXEo5QKHQWdCTMQFgg2MAE&amp;amp;url=https%3A%2F%2Fwww.ics.uci.edu%2F~fielding%2Fpubs%2Fdissertation%2Ffielding_dissertation.pdf&amp;amp;usg=AFQjCNEEwS3STct3jnKXToOQXO15Q4cY1g&quot;&gt;PDF 파일&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api&quot;&gt;Best Practices for Designing a Pragmatic RESTful API&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://pages.apigee.com/rs/apigee/images/api-design-ebook-2012-03.pdf&quot;&gt;PDF: Web API Design Crafting Interfaces that Developers Love&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-Kihe6YpYKTxWlvaE-xz&quot;&gt;RESTful API 설계&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-Kj6o0MYeqXWkmV7uR_s&quot;&gt;테스트를 활용한 Restful API 개발&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-KiheRpKnPav7jqwECvw&quot;&gt;테스트, 객체 지향 프로그래밍&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-spring-boot/tree/step10-delete-question-completed&quot;&gt;과제 참고용 교수님 저장소&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 29 May 2017 19:54:06 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/29/jwp-15/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/29/jwp-15/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 14</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-네-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-네-번째-수업-이모저모&quot;&gt;열 네 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#프로그래밍-단상-변화를-어떻게-만들어갈-것인가&quot; id=&quot;markdown-toc-프로그래밍-단상-변화를-어떻게-만들어갈-것인가&quot;&gt;프로그래밍 단상: 변화를 어떻게 만들어갈 것인가?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#immutable-객체-메모&quot; id=&quot;markdown-toc-immutable-객체-메모&quot;&gt;immutable 객체 메모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#orm---jpa&quot; id=&quot;markdown-toc-orm---jpa&quot;&gt;ORM - JPA&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;열-네-번째-수업-이모저모&quot;&gt;열 네 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-25 19:00:00 +0900&lt;/code&gt; 무렵에 시작했을 것으로 추측.
    &lt;ul&gt;
      &lt;li&gt;이번 수업엔 내가 3 분 정도 지각했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;오늘은 ORM을 사용해 본다.&lt;/li&gt;
  &lt;li&gt;이제 종강까지 수업 두 번 남았다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;프로그래밍-단상-변화를-어떻게-만들어갈-것인가&quot;&gt;프로그래밍 단상: 변화를 어떻게 만들어갈 것인가?&lt;/h1&gt;

&lt;p&gt;회고를 통해 얻은 깨달음을 토대로 작은 성공을 반복해 가는 사이클.&lt;/p&gt;

&lt;p&gt;작은 변화들의 누적으로 인한 큰 변화의 발생을 기대하는 방식이 마음에 든다.&lt;/p&gt;

&lt;h1 id=&quot;immutable-객체-메모&quot;&gt;immutable 객체 메모&lt;/h1&gt;

&lt;p&gt;어지간한 경우엔 그냥 불변 객체를 쓰는 쪽이 좋다고 생각한다.
자잘한 버그가 줄어들고, 읽기도 더 편하다. 사이드 이펙트를 관리하기도 좋다.&lt;/p&gt;

&lt;p&gt;Java에서는 불변 객체의 사용이 꽤 번거로운 편이므로
Scala 같은 언어를 사용하는 것도 좋다고 생각한다.&lt;/p&gt;

&lt;p&gt;덧붙이자면 객체 뿐 아니라 변수의 사용도 자제하고,
가능한 한 상수만을 사용해서 코딩하는 것도 좋다고 생각한다.&lt;/p&gt;

&lt;h1 id=&quot;orm---jpa&quot;&gt;ORM - JPA&lt;/h1&gt;

&lt;p&gt;이 책 한 권이면 된다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.acornpub.co.kr/book/jpa-programmig&quot;&gt;자바 ORM 표준 JPA 프로그래밍&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-Kk9mNZRospN5eO7duC0&quot;&gt;프로그래밍 단상&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-Kihe0w5_EXX4St6SZcT&quot;&gt;ORM 및 Spring Data JPA&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 27 May 2017 18:00:40 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/27/jwp-14/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/27/jwp-14/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 13</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-세-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-세-번째-수업-이모저모&quot;&gt;열 세 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;열-세-번째-수업-이모저모&quot;&gt;열 세 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-22 19:00:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;회고에 대한 이야기
    &lt;ul&gt;
      &lt;li&gt;회고는 소프트웨어 개발 프로세스에서 가장 중요한 활동 중 하나.&lt;/li&gt;
      &lt;li&gt;회고를 할 때 팀원간의 감정 공유도 매우 중요하다.
        &lt;ul&gt;
          &lt;li&gt;감사 메시지 남기기&lt;/li&gt;
          &lt;li&gt;서로, 스스로 칭찬하기&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이번 수업 내용은 다소 까다롭고 난이도가 높았다.
교수님 레파지토리를 보고 곱씹어 보는 시간이 필요할듯.&lt;/p&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-spring-boot/tree/step2-refactoring&quot;&gt;교수님 레파지토리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-KihdwAUJKQvBDvkGCmQ&quot;&gt;AOP 개념 및 로그인 기반 테스트&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-KkPXQQuTJB7TSIF7f4a&quot;&gt;Spring AOP 및 LoggingAspect&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 23 May 2017 22:05:44 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/23/jwp-13/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/23/jwp-13/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 12</title>
        <description>&lt;h1 id=&quot;열-두-번째-수업-이모저모&quot;&gt;열 두 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-18 19:00:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;오늘부터는 Spring Boot를 공부한다.&lt;/li&gt;
  &lt;li&gt;오늘의 목표는 교수님을 따라 Spring Boot 애플리케이션을 작성하고, 배포까지 하는 것.
    &lt;ul&gt;
      &lt;li&gt;그러나 프로젝트를 만드는 과정에서 너무 많은 시간이 소요되는 사람들이 몇 명 있었다.&lt;/li&gt;
      &lt;li&gt;그 중에 나도 있었다. (아마 내가 제일 오래 걸린듯 하다)&lt;/li&gt;
      &lt;li&gt;프로젝트 셋팅에 시간이 너무 오래 걸려, 수업 목표가 바뀌었다.
        &lt;ul&gt;
          &lt;li&gt;배포는 포기하고 애플리케이션 작성 완료를 목표로.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;IntelliJ에서 새로운 Spring Boot 프로젝트를 만들고 빌드하는 과정이 너무 힘들었다.
    &lt;ul&gt;
      &lt;li&gt;뭘 어떻게 해도 자꾸 에러가 발생했다.&lt;/li&gt;
      &lt;li&gt;두 시간 가까이 삽질을 했고 규진님의 도움으로 가까스로 셋팅을 완료하고 코딩에 들어갈 수 있었다.&lt;/li&gt;
      &lt;li&gt;이후엔 개인적으로 급한 일이 생겨 일찍 집으로 돌아갔다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;책 소개 : &lt;a href=&quot;https://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788966260836&quot;&gt;객체지향 설계와 실천&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;오늘의 강의 내용은 이 책과 관련이 깊음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;아마추어와-프로의-차이&quot;&gt;아마추어와 프로의 차이&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;책 소개: &lt;a href=&quot;https://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9791186805282&quot;&gt;1만 시간의 재발견&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;심리학자 말콤 글래드웰이 만든 1만 시간의 법칙을 비판하는 책으로 보인다.&lt;/li&gt;
  &lt;li&gt;1만 시간의 법칙은 반례가 충분히 많기 때문에 과학 이론으로서는 결함이 많다고 생각해왔다. 기본적으로는 생각해왔던 것들과 큰 차이가 없을 것 같아서 책 자체에 큰 흥미가 생기진 않는다. 나중에 서점 가서 대충 훑어볼 생각.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;과제-수행&quot;&gt;과제 수행&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업을 끝까지 듣지 못했으므로 무엇이 과제인지 알지 못한다.&lt;/li&gt;
  &lt;li&gt;따라서 수업 교재를 보고 수업 시간에 따라하지 못한 것을 완료할 것을 목표로 삼고 작업을 시작하였다.&lt;/li&gt;
  &lt;li&gt;그런데 이번 주말엔 이런 저런 일로 시간이 부족해서 과제에 쏟을 시간이 충분하지 못하여, 교수님의 저장소를 참고하고 따라 해 보는 정도로 만족하기로 했다.&lt;/li&gt;
  &lt;li&gt;브라우저를 열지 않고 웹 개발을 한다는 다소 모순된 것 같은 방식에 점차 익숙해지고 있다. 너무 좋다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;과제 완료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-spring-boot&quot;&gt;참고 자료: 교수님의 저장소&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/test-spring-boot/tree/step1-johngrib&quot;&gt;내 과제 수행 결과&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KihchAcnJJxzb909TBT/lessons/-KjqDMIMMiyhMCImA8Hw&quot;&gt;점진적 소프트웨어 개발 by 테스트&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 20 May 2017 20:44:40 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/20/jwp-12/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/20/jwp-12/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 11</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-한-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-한-번째-수업-이모저모&quot;&gt;열 한 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#mockito-테스트-실습&quot; id=&quot;markdown-toc-mockito-테스트-실습&quot;&gt;Mockito 테스트 실습&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;열-한-번째-수업-이모저모&quot;&gt;열 한 번째 수업 이모저모&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-15 19:00:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;이제 수업이 3주 남았다.
    &lt;ul&gt;
      &lt;li&gt;다음 주 부터는 5회에 걸쳐 Spring Boot를 학습한다.&lt;/li&gt;
      &lt;li&gt;마지막 수업엔 개발한 Spring Boot 어플리케이션의 배포를 실습한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이론 수업
    &lt;ul&gt;
      &lt;li&gt;빈 컨테이너 설정 관리&lt;/li&gt;
      &lt;li&gt;Spring life cycle&lt;/li&gt;
      &lt;li&gt;Property Source 및 환경 변수&lt;/li&gt;
      &lt;li&gt;Java Bean Validation&lt;/li&gt;
      &lt;li&gt;DI 기반 단위 테스트&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;피자/맥주 파티
    &lt;ul&gt;
      &lt;li&gt;약 21시부터 피자/맥주 파티를 하며 담소를 나누었다.&lt;/li&gt;
      &lt;li&gt;나는 피자/맥주/콜라 모두 안 먹는 음식들이라 생수만 마셨다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;mockito-테스트-실습&quot;&gt;Mockito 테스트 실습&lt;/h2&gt;

&lt;p&gt;Mockito를 사용하니 어렵지 않고 깔끔하게 끝낼 수 있었다.
약간 우려스러운 점이 있긴 하지만 아직은 Mockito를 잘 모르니 좀 더 익숙해지면 생각해보도록 하자.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@RunWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MockitoJUnitRunner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QnaServiceTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Mock&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QuestionDao&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Mock&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AnswerDao&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;


    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QnaService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Before&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 로그인 사용자와 질문한 사람이 같아야 한다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Positive_질문한_사람과_삭제하려는_사람이_같으면_삭제할_수_있다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 로그인 사용자와 질문한 사람이 같아야 한다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Negative_질문한_사람과_삭제하려는_사람이_다르면_삭제할_수_없다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;otherUser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;삭제하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;otherUser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 답변이 없는 경우 삭제가 가능하다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Positive_답변이_없는_경우_삭제가_가능하다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findAllByQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;EMPTY_LIST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 답변이 없는 경우 삭제가 가능하다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Negative_답변이_있다면_삭제할_수_없다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;답변하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findAllByQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 질문자와 답변자가 같은 경우 삭제가 가능하다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Positive_답변이_있어도_질문자와_답변자가_같다면_삭제할_수_있다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findAllByQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 질문자와 답변자가 다른 경우 답변을 삭제할 수 없다.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Negative_답변이_있을_때_질문자와_답변자가_다르면_삭제할_수_없다&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CannotOperateException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질문하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;답변하는 사람 아이디&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;제목&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;내용&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;questionDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answerDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findAllByQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;qnaService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deleteQuestion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getQuestionId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;links&quot;&gt;Links&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;과제 완료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/jwp-spring/tree/step2-johngrib&quot;&gt;Mockito 테스트 실습&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9qPOW42m1nnuoyvXz/lessons/-KiY-AXcRm8DhRdOy5Rv&quot;&gt;DI 기반 단위 테스트&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 May 2017 21:36:06 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/16/jwp-11/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/16/jwp-11/</guid>
        
        <category>study jwp mockito DI</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 10</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#열-번째-수업-이모저모&quot; id=&quot;markdown-toc-열-번째-수업-이모저모&quot;&gt;열 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상-삶과-프로그래밍&quot; id=&quot;markdown-toc-단상-삶과-프로그래밍&quot;&gt;단상: 삶과 프로그래밍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#di-프레임워크-1단계-실습&quot; id=&quot;markdown-toc-di-프레임워크-1단계-실습&quot;&gt;DI 프레임워크 1단계 실습&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;열-번째-수업-이모저모&quot;&gt;열 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-11 19:03:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;오늘은 지난 시간 feedback 후 DI를 구현하는 연습을 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상-삶과-프로그래밍&quot;&gt;단상: 삶과 프로그래밍&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;어떻게 일할 것인가?&lt;/li&gt;
  &lt;li&gt;내가 일지를 작성하는 방식을 공유하였다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;di-프레임워크-1단계-실습&quot;&gt;DI 프레임워크 1단계 실습&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;요구사항&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;새로 만든 MVC 프레임워크는 자바 리플렉션을 활용해 @Controller 애노테이션이 설정되어 있는 클래스를 찾아 인스턴스를 생성하고, URL 매핑 작업을 자동화했다. 같은 방법으로 각 클래스에 대한 인스턴스 생성 및 의존관계 설정을 애노테이션으로 자동화한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;먼저 애노테이션은 각 클래스 역할에 맞도록 컨트롤러는 이미 추가되어 있는 @Controller, 서비스는 @Service, DAO는 @Repository 애노테이션을 설정한다. 이 3개의 설정으로 생성된 각 인스턴스 간의 의존관계는 @Inject 애노테이션을 사용한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step10-johngrib&quot;&gt;GitHub&lt;/a&gt;에 올려두었다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;교수님은 다들 부담스럽겠지만 재귀를 사용해야 할 것이라며 재귀를 강조하셨지만, 나는 오히려 for loop보다 재귀를 선호하는 편이므로 자신만만하게 작업을 시작했다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;그러나 몇 가지 메서드가 이미 구현되어 있다는 걸 생각하지 못했고, (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeanFactoryUtils.getInjectedConstructor&lt;/code&gt;나, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeanFactoryUtils.findConcreteClass&lt;/code&gt; 등) Repository 도 구현된 게 있다는 걸 발견하지 못해서 3 시간 가까이 갈피를 잡지 못하고 헤메이다 간신히 힌트를 보고 숙제를 할 수 있었다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;일요일까지 끌고 오긴 했지만(…) 과제를 완수할 수 있어서 다행이라 생각한다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step10-johngrib&quot;&gt;과제 완료&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection&quot;&gt;Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-Ki7rZnr3DpctbqOtJQn&quot;&gt;삶과 프로그래밍: 어떻게 일할 것인가?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9qPOW42m1nnuoyvXz/lessons/-KiXzwhTznbMAcSlMO7w&quot;&gt;DI 프레임워크 1단계 실습 및 힌트&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 14 May 2017 14:10:50 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/14/jwp-10/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/14/jwp-10/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 09</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#아홉-번째-수업-이모저모&quot; id=&quot;markdown-toc-아홉-번째-수업-이모저모&quot;&gt;아홉 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상-삶과-프로그래밍&quot; id=&quot;markdown-toc-단상-삶과-프로그래밍&quot;&gt;단상: 삶과 프로그래밍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#메모-spring-annotation&quot; id=&quot;markdown-toc-메모-spring-annotation&quot;&gt;메모: Spring Annotation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#메모-refactoring-fp-oop&quot; id=&quot;markdown-toc-메모-refactoring-fp-oop&quot;&gt;메모: Refactoring, FP, OOP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#spring-mvc-실습&quot; id=&quot;markdown-toc-spring-mvc-실습&quot;&gt;Spring MVC 실습&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;아홉-번째-수업-이모저모&quot;&gt;아홉 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-05-08 19:01:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;사내 교육장이 완성되어, 이제부터는 소마 미술관에 가지 않아도 된다.
    &lt;ul&gt;
      &lt;li&gt;다만 교육장 내부 시설은 아직 정비가 필요한 듯하다. 간이 책상과 의자를 사용했고, 교육장 앞쪽에 컴퓨터를 둘 수 없어, 박재성 교수님이 앞뒤로 이동하며 강의하셔야 했음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;오늘은 MVC 프레임워크 실습 피드백을 하고, Spring 실습을 한다.&lt;/li&gt;
  &lt;li&gt;QnA가 다른 시간보다 활발한 편이었다. 리팩토링에 대한 이야기가 주를 이루었음.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상-삶과-프로그래밍&quot;&gt;단상: 삶과 프로그래밍&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;권위: 동의할 수 없는 권위에 굴복하지 말 것.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;메모-spring-annotation&quot;&gt;메모: Spring Annotation&lt;/h1&gt;

&lt;p&gt;스프링엔 어노테이션이 도입되지 않았던 시절도 있었다. 어노테이션 없이도 훌륭한 스프링 애플리케이션을 만드는 것은 가능할 것이다. 그러나 스프링 어노테이션의 존재를 알면서도 사용하지 않는 사람은 매우 드물 거라고 생각한다.&lt;/p&gt;

&lt;p&gt;내 관점에서 현재의 스프링은 거대한 리플렉션 라이브러리다. 스프링은 리플렉션을 사용한 어노테이션 기능을 잔뜩 구현해 놓음으로써, 사용자가 리플렉션의 필요를 느끼지 못하게 만들었다.&lt;/p&gt;

&lt;p&gt;나는 리플렉션이 Java답지 않은 기능이라고 생각한다. Java의 중요한 특징인 강한 타입과 IDE 지원을 무시하는 코드가 생산되기 때문이다. 게다가 결과물은 Exception이 잔뜩 붙어 있어 참기 어려운 고약한 냄새가 난다. 하지만 Java의 문법만으로는 몇몇 작업을 수행할 때 한계가 있으니 울며 겨자 먹기로 사용할 수 밖에 없다.&lt;/p&gt;

&lt;p&gt;하지만 스프링이 있다면 사용자의 코드에서는 리플렉션이 사라지게 된다. 스프링 어노테이션은 환상적인 기능이다. 클래스와 메서드에 어노테이션 스탬프만 쾅쾅 찍어 놓으면 프레임워크가 알아서 리플렉션으로 처리해준다. 이는 내가 좋아하는 스티브 맥코넬의 &apos;최종 목표&apos;와도 걸맞는 일이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;최종 목표는 한번에 생각해야 하는 프로그램의 양을 최소화하는 것이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;스프링은 Java 프레임워크의 정점이라는 생각까지 들고 있다. 그러나 이것이 과연 바람직한 일일까? 로드 존슨이 어노테이션 도입을 반대했다는 이야기를 얼핏 들은 것 같은데, 아마도 스프링 어노테이션으로 인한 커플링을 걱정했던 모양이다.&lt;/p&gt;

&lt;p&gt;루비 온 레일즈에 대한 비판을 찾아보는 것도 좋을 것 같다.&lt;/p&gt;

&lt;h1 id=&quot;메모-refactoring-fp-oop&quot;&gt;메모: Refactoring, FP, OOP&lt;/h1&gt;

&lt;p&gt;OOP Language에서 Functional Language로 넘어가는 작업을 해 본 적이 있었다. Java에서 Scala로. 전체적인 구조는 OOP 형식으로 잡고 메서드 단위에서는 FP 방식으로 코딩하는 쪽으로 작업을 했는데 썩 만족스러웠다.&lt;/p&gt;

&lt;p&gt;그러나 돌이켜 생각해보니 아쉬운 마음이 든다.&lt;/p&gt;

&lt;p&gt;전체적인 구조를 OOP로 잡고, 메서드 단위에서 FP의 이념을 구현한 것은… 현실적인 대안이긴 했지만 FP라 부르기에는 많이 부족했다고 생각한다. 패러다임이 바뀌지 않았기 때문이다. 결과물은 여전히 객체들 사이의 상호작용이었다.&lt;/p&gt;

&lt;p&gt;Java에서는 함수를 동적으로 생성해 리턴하거나, 일반 동사처럼 작동하는 여러 개의 기본 함수를 합성해 한 번만 사용하거나 하는 일들이 어렵거나 때로는 불가능하다. OOP 하 FP 스타일의 메서드 구현이란 궁여지책은, 함수가 스스로 존재할 수 없으며 클래스에 내재되어야 하는 구조이기 때문에 그렇게 작업할 수 밖에 없는 Java의 문법, Java의 OOP 패러다임에 지나치게 익숙했기 때문에 비롯된 것이었다고 생각한다.&lt;/p&gt;

&lt;p&gt;물론 나는 그 경험이 나쁜 경험이었다고는 생각하지 않는다. 좋은 경험에 가깝다. FP 언어로 넘어갔음에도 불구하고 안타깝게도 패러다임이 전환에 실패한 경험일 뿐이다. OOP 코드는 FP 메서드를 뿌려줘도 계속 OOP 코드일 수 밖에 없다는 교훈을 얻었다.&lt;/p&gt;

&lt;h1 id=&quot;spring-mvc-실습&quot;&gt;Spring MVC 실습&lt;/h1&gt;

&lt;p&gt;강의는 Spring 아키텍처에 대한 내용이 주를 이루었다.&lt;/p&gt;

&lt;p&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp-spring/tree/step1-johngrib&quot;&gt;GitHub&lt;/a&gt;에 올려두었다.&lt;/p&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/jwp-spring/tree/step1-johngrib&quot;&gt;step1 과제 완료&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://sangwook.github.io/2016/06/14/ruby-rails-solnic.html&quot;&gt;&quot;Rails 이제 안 써&quot; 를 읽고&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://solnic.eu/2016/05/22/my-time-with-rails-is-up.html&quot;&gt;My time with Rails is up&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-Ki7rZnr3DpctbqOtJQn&quot;&gt;삶과 프로그래밍: 권위&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9leY0VnZi2akOLdkW/lessons/-KiczjAzomD4tthzbxCE&quot;&gt;MVC 프레임워크 3단계 실습 피드백&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9leY0VnZi2akOLdkW/lessons/-KiXzmz-fArFcxPxgjH_&quot;&gt;Spring MVC 실습&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 09 May 2017 10:45:58 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/09/jwp-09/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/09/jwp-09/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Vim 사용시 한/영 전환 문제 해결하기</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#짜증나는-한영전환을-완벽히-해결해-보자&quot; id=&quot;markdown-toc-짜증나는-한영전환을-완벽히-해결해-보자&quot;&gt;짜증나는 한영전환을 완벽히 해결해 보자&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#langmap을-사용하는-방법&quot; id=&quot;markdown-toc-langmap을-사용하는-방법&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;langmap&lt;/code&gt;을 사용하는 방법&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#구름-입력기를-사용하는-방법&quot; id=&quot;markdown-toc-구름-입력기를-사용하는-방법&quot;&gt;구름 입력기를 사용하는 방법&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#karabiner를-사용하는-방법&quot; id=&quot;markdown-toc-karabiner를-사용하는-방법&quot;&gt;karabiner를 사용하는 방법&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#hammerspoon을-사용하는-방법&quot; id=&quot;markdown-toc-hammerspoon을-사용하는-방법&quot;&gt;hammerspoon을 사용하는 방법&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;짜증나는-한영전환을-완벽히-해결해-보자&quot;&gt;짜증나는 한영전환을 완벽히 해결해 보자&lt;/h2&gt;

&lt;p&gt;Vim을 사용할 때 가장 짜증나는 일은 한국어로 주석을 적다가 Normal 모드로 들어갔을 때 한국어 글자가 입력되어 명령이 제대로 먹히지 않는 경우일 것이다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt;를 입력할 때마다 영문으로 바뀌면 좋은데, 방법을 모를 때에는 일일이 영문으로 전환해주고 모드를 변경해주는 수고를 해 주어야 한다.&lt;/p&gt;

&lt;p&gt;지금이야 이런 저런 꼼수들을 적용해놔서 생각할 필요가 없는 문제이긴 하다.&lt;/p&gt;

&lt;p&gt;그러나 이걸 아예 잊고 살다가 나중에 다 까먹고 새로운 환경에서 삽질할 일을 방지하기 위해 글을 남겨두기로 했다.&lt;/p&gt;

&lt;h3 id=&quot;langmap을-사용하는-방법&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;langmap&lt;/code&gt;을 사용하는 방법&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;langmap&lt;/code&gt;을 사용하면 꼭 영문이 아니어도 Normal 모드에서 명령을 입력할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-viml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;langmap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;ㅁ&lt;span class=&quot;k&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅠ&lt;span class=&quot;k&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅊ&lt;span class=&quot;k&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅇ&lt;span class=&quot;k&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㄷ&lt;span class=&quot;k&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㄹ&lt;span class=&quot;k&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅎ&lt;span class=&quot;k&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅗ&lt;span class=&quot;k&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅑ&lt;span class=&quot;k&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅓ&lt;span class=&quot;k&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅏ&lt;span class=&quot;k&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅣ&lt;span class=&quot;k&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅡ&lt;span class=&quot;k&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅜ&lt;span class=&quot;k&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅐ&lt;span class=&quot;k&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅔ&lt;span class=&quot;k&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅂ&lt;span class=&quot;k&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㄱ&lt;span class=&quot;k&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㄴs&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅅ&lt;span class=&quot;k&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅕ&lt;span class=&quot;k&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅍ&lt;span class=&quot;k&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅈ&lt;span class=&quot;k&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅌ&lt;span class=&quot;k&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅛ&lt;span class=&quot;k&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;ㅋz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Vim 자체의 설정만을 사용하는 방법이라 썩 괜찮은 방법. 그러나 명령을 입력할 때마다 한국어 글쇠의 잔상이 남아서 보기 껄끄럽고 신경쓰인다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;langmap&lt;/code&gt;을 지원하지 않는 IDE Vim plugin 에서 사용할 수 없다는 것도 문제.&lt;/p&gt;

&lt;h3 id=&quot;구름-입력기를-사용하는-방법&quot;&gt;&lt;a href=&quot;http://gureum.io/&quot;&gt;구름 입력기&lt;/a&gt;를 사용하는 방법&lt;/h3&gt;

&lt;p&gt;mac 이라면 구름 입력기를 사용하여 쉽게 해결 가능하다.&lt;br /&gt;
구름 입력기에는 다음과 같은 엄청난 옵션들이 있기 때문이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt;를 입력할 때마다 영문으로 변경&lt;/li&gt;
  &lt;li&gt;영문으로 전환하는 단축키 지정&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;입력기 자체를 바꾸는 것이기 때문에 Vim 이건 IDE Vim Plugin 이건 설정을 바꿔줄 필요가 없다.
특히 영문 전환 단축키를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-c&amp;gt;&lt;/code&gt; 나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-[&amp;gt;&lt;/code&gt; 등으로 설정해 주는 것도 가능해서 활용하기 좋다.
복잡하게 설정하기 귀찮다면 가장 이상적인 해결책이라 생각한다. 실제로 구름 입력기 설정만으로도 1년이 넘게 잘 썼다.&lt;/p&gt;

&lt;p&gt;하지만 네이티브 입력기가 아니라서 그런지, mac Sierra 부터는 iTerm 에서 속도 저하 문제가 있다. Normal 명령어 몇 개 빠르게 입력하기만 해도 딜레이가 생겨서 좀 답답하다.&lt;/p&gt;

&lt;p&gt;또한 IntelliJ IDEA 의 Vim Plugin인 Ideavim 과 상성이 별로 좋지 않다. 구름 입력기 옵션에 IntelliJ 관련 설정이 있긴 하지만, 설정을 해도 사용하다 보면 모드 전환이 한 번에 안 되는 등의 불만족스러운 상황을 자주 만나게 된다.&lt;/p&gt;

&lt;h3 id=&quot;karabiner를-사용하는-방법&quot;&gt;karabiner를 사용하는 방법&lt;/h3&gt;

&lt;p&gt;구 karabiner 에서는 아래와 같은 설정을 써서 한 번에 해결이 가능했다.
나는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F15&lt;/code&gt; 키를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Capslock&lt;/code&gt; 에 매핑해 두었었기 때문에, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt; 대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Capslock&lt;/code&gt;만 누르면 편리하게 모드 전환을 할 수 있었다.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;vkchangeinputsourcedef&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;KeyCode::VK_CHANGE_INPUTSOURCE_TO_ENGLISH&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;inputsourceid_equal&amp;gt;&lt;/span&gt;com.apple.keylayout.ABC&lt;span class=&quot;nt&quot;&gt;&amp;lt;/inputsourceid_equal&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/vkchangeinputsourcedef&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt;F15_abc_escape&lt;span class=&quot;nt&quot;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;F15 : abc 로 inputsource 전환 후, ESC 입력&lt;span class=&quot;nt&quot;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;autogen&amp;gt;&lt;/span&gt;
        __KeyOverlaidModifier__
        KeyCode::F15,
        KeyCode::VK_MODIFIER_EXTRA1,
        KeyCode::VK_CHANGE_INPUTSOURCE_TO_ENGLISH,
        KeyCode::ESCAPE,
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/autogen&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;문제는 mac Sierra 부터 사용할 수 없게 되었다는 점. karabiner 가 Sierra에서는 작동하지 않기 때문에 이제는 알아봐야 소용이 없는 방법이다. 여기에 추가한 이유는 그냥 기록을 남겨 놓고 싶어서이다.&lt;/p&gt;

&lt;p&gt;karabiner 를 사용할 수 없게 되자, karabiner의 개발자분이 &lt;a href=&quot;https://github.com/tekezo/Karabiner-Elements&quot;&gt;karabiner-elements&lt;/a&gt;를 급히 개발해 내놓긴 했지만 karabiner 를 통해 사용할 수 있었던 기능 대부분을 사용할 수 없는 상태. 현재로서는 그냥 키 1:1 매핑 밖에 안 된다.&lt;/p&gt;

&lt;h3 id=&quot;hammerspoon을-사용하는-방법&quot;&gt;hammerspoon을 사용하는 방법&lt;/h3&gt;

&lt;p&gt;내가 가장 선호하는 방법이다. &lt;a href=&quot;http://www.hammerspoon.org/&quot;&gt;hammerspoon&lt;/a&gt;은 mac을 위한 일종의 매크로 툴로서, Windows 진영의 &lt;a href=&quot;https://autohotkey.com/&quot;&gt;autohotkey&lt;/a&gt;와 비슷한 느낌으로 쓸 수 있다. 기능도 비슷하고 할 수 있는 일도 비슷. 다만 lua 를 쓰기 때문에 autohotkey 보다는 좀 더 쓸만한 언어로 작업을 할 수 있다는 장점이 있다.&lt;/p&gt;

&lt;p&gt;hammerspoon에서 다음과 같은 코드를 특정 키에 바인딩해주면 해당 키를 입력할 때마다 무조건 영문으로 변경되고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-c&amp;gt;&lt;/code&gt;를 추가로 입력하기 때문에 Vim 에서는 Normal 모드로 변경된다.&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputEnglish&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;com.apple.keylayout.ABC&quot;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keycodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentSourceID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputEnglish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eventtap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyStroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({},&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;right&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keycodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentSourceID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputEnglish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eventtap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyStroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;control&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt; 가 아니라 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-c&amp;gt;&lt;/code&gt; 가 입력되게 한 이유는 iTerm 에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Meta&lt;/code&gt; 키를 사용하는 그나마 적절한 방법이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt;를 사용하는 것 뿐이기 때문이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;아무튼 이 방법을 사용하면 네이티브 입력기를 사용하기 때문에 커서 움직임이 구름 입력기에 비해 엄청나게 빠르고, IntelliJ의 Ideavim에서나 터미널 Vim에서나 똑같이 사용할 수 있다는 장점이 있다. hammerspoon을 적극적으로 여러 방향으로 사용하고 있는 내게는 현재 가장 적절한 방법이라 생각한다.&lt;/p&gt;

&lt;h2 id=&quot;links&quot;&gt;Links&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://gureum.io/&quot;&gt;구름 입력기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/tekezo/Karabiner-Elements&quot;&gt;karabiner-elements&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://autohotkey.com/&quot;&gt;autohotkey&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.hammerspoon.org/&quot;&gt;hammerspoon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 04 May 2017 22:05:30 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/04/input-source/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/04/input-source/</guid>
        
        <category>vim 구름입력기 hammerspoon karabiner input-source</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 08</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#여덟-번째-수업-이모저모&quot; id=&quot;markdown-toc-여덟-번째-수업-이모저모&quot;&gt;여덟 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상--삶과-프로그래밍&quot; id=&quot;markdown-toc-단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#reflection&quot; id=&quot;markdown-toc-reflection&quot;&gt;Reflection&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#mvc-framework-구현&quot; id=&quot;markdown-toc-mvc-framework-구현&quot;&gt;MVC Framework 구현&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;여덟-번째-수업-이모저모&quot;&gt;여덟 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-27 19:00:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;오늘은 Reflection 연습을 하고, annotation 기반의 MVC Framework를 만들어 본다.
    &lt;ul&gt;
      &lt;li&gt;Reflection에 익숙한 사람은 Framework 만들기로 바로 들어가기로 한다.&lt;/li&gt;
      &lt;li&gt;나는 Reflection에 익숙한 편이라고 스스로 판단하고 Framework 만들기로 바로 들어갔다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;몰입
    &lt;ul&gt;
      &lt;li&gt;몰입은 단순히 작업 능률에만 영향을 주는 것이 아니라, 삶과 행복과도 관련이 있다.&lt;/li&gt;
      &lt;li&gt;그렇다면 어떻게 몰입할 것인가?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;reflection&quot;&gt;Reflection&lt;/h1&gt;

&lt;p&gt;나는 Java로 코드를 작성할 때 Reflection을 즐겨 쓰는 편이지만 Reflection을 썩 좋아하지는 않는다.
Reflection을 써서 코딩하고 있다 보면 Java의 아이덴티티가 희석되는 느낌이 들기 때문이다.&lt;/p&gt;

&lt;p&gt;나는 Java 문법상의 한계가 Reflection에서 드러난다고 생각한다.
그리고 Reflection이 Java의 장점에 해를 끼친다고 본다.&lt;/p&gt;

&lt;p&gt;나는 딱히 자신 있는 언어가 없고, Java에 대해서도 아직 초심자에 속한다고 생각한다.
정적 타입 언어보다는 동적 타입 언어가 더 성격에 맞는 편이다.
그럼에도 불구하고 뭔가 새로운 것을 만들 때, 나는 Java를 항상 중요한 선택지 중의 하나로 고려한다.
왜냐하면 Java는 컴파일 타임에서 꽤 많은 실수를 걸러낼 수 있기 때문이다.
그게 가능하기 때문에 Java IDE의 신뢰할 수 있는 대규모 리팩토링이나 스마트한 자동완성도 가능하다.&lt;/p&gt;

&lt;p&gt;그런데 Reflection을 적극적으로 사용하게 되면 컴파일 타임에서 얻을 수 있는 이득을 상당부분 포기해야 한다.
내 기준으로 Java를 선택할 중요한 이유가 사라지는 셈이다.&lt;/p&gt;

&lt;p&gt;하지만 그럼에도 불구하고 Java는 현대 산업에 있어 중요한 언어이고
그러한 Java의 한계를 극복하게 해 주는 Reflection은 주요 프레임워크들에 의해 널리 사용되고 있다.
물론 Reflection이 제한 없이 사용되는 건 아닌 모양이다.
Reflection은 프로그램 가동시에만 사용하고, 가능한 한 검증된 라이브러리에 수록된 것만 사용해야 한다는
암묵적인 원칙이 공유되고 있는 느낌이다.&lt;/p&gt;

&lt;p&gt;폴 그레이엄이 Java를 두고 실수 예방에 초점을 맞춘 언어라고 했던 게 생각난다.
&lt;a href=&quot;http://paulgraham.com/javacover.html&quot;&gt;폴 그레이엄은 Java를 까면서&lt;/a&gt; 그런 말을 했지만,
사실 Java는 실수 예방에 굉장히 뛰어난 언어이기 때문에 주류 언어가 되었고
앞으로도 꽤 오랫동안 산업계에서 사랑받을 거라고 생각한다.&lt;/p&gt;

&lt;p&gt;그러고보니 래리 월은 &lt;a href=&quot;https://youtu.be/LR8fQiskYII?t=1m39s&quot;&gt;Java가 좋은 의미의 현대판 Cobol&lt;/a&gt;이라 했었던 것 같다.
&lt;del&gt;(어느 문서에서 말했는지는 잘 기억이 안 나는데 링크를 찾아다 붙여놓을 예정이다)&lt;/del&gt;&lt;/p&gt;

&lt;h1 id=&quot;mvc-framework-구현&quot;&gt;MVC Framework 구현&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step8-johngrib&quot;&gt;GitHub Repository&lt;/a&gt;에 올려두었다.&lt;/li&gt;
  &lt;li&gt;Reflection을 사용해서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Controller&lt;/code&gt; 어노테이션과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@RequestMapping&lt;/code&gt; 어노테이션을 수집하고, 그에 따라 요청을 처리하도록 수정하였다. 아래는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UserController.java&lt;/code&gt;의 내용을 축약한 것이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Controller&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/users&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserController&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;UserController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserDao&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userDao&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserDao&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/form&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/create&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RequestMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/update&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RequestMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/updateForm&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateForm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/profile&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 생략&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;url에 중복이 많아서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Controller&lt;/code&gt;에 prefix를 지정할 수 있도록 작업해 봤다.&lt;/li&gt;
  &lt;li&gt;하나하나의 메서드가 각각의 Request를 담당하게 되니 여러 Controller 클래스를 하나로 합칠 수 있었다.&lt;/li&gt;
  &lt;li&gt;이정도면 일단 만족. Spring이랑 비슷한 모양이 나오네.&lt;/li&gt;
  &lt;li&gt;아, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DispatcherServlet&lt;/code&gt;은 다음과 같은 모양을 갖추게 되었다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@WebServlet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dispatcher&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlPatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadOnStartup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DispatcherServlet&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServlet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serialVersionUID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1L&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;DispatcherServlet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ControllerMapping&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controllerMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServletException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;controllerMap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ControllerMapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;annotation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Controller&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;next.controller&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HttpServletRequest&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HttpServletResponse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServletException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestUri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRequestURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Method : {}, Request URI : {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestUri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ControllerData&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controllerData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controllerMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRequestURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelAndView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mav&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controllerData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mav&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mav&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Exception : {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ServletException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step8-johngrib&quot;&gt;step8 과제 완료&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.journaldev.com/4098/java-heap-space-vs-stack-memory&quot;&gt;JournalDev : Java Heap Space vs Stack – Memory Allocation in Java&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://paulgraham.com/javacover.html&quot;&gt;Paul Graham : Java&apos;s Cover&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.fupfin.com/?p=102&quot;&gt;Paul Graham : Java&apos;s Cover(한국어)&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;폴 그레이엄은 Java를 매우 까는 입장인데, Java를 사랑하는 사람이라면 이 글을 읽기 전에 심호흡을 하고, 그가 엄청나게 하드코어한 Lisp 해커라는 점을 염두에 두길 바란다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/LR8fQiskYII?t=1m39s&quot;&gt;Larry Wall : 5 Programming Languages Everyone Should Know&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.ted.com/talks/mihaly_csikszentmihalyi_on_flow?language=ko#t-1033416&quot;&gt;TED : 미하이 칙센트미하이의 몰입&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://egloos.zum.com/agile/v/5749946&quot;&gt;당신이 제자리 걸음인 이유 : 지루하거나 불안하거나&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9lXoEYVTp6w6Nkl3t/lessons/-Kh_ghT2zXD6EMC6Ix5e&quot;&gt;상태 점검에 따른 피드백&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9leY0VnZi2akOLdkW/lessons/-Khyfd6JtntTR9BwsGVR&quot;&gt;자바 Reflection 실습&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9leY0VnZi2akOLdkW/lessons/-KhyffvIV_kFgKjRrGOi&quot;&gt;MVC 프레임워크 3단계 실습&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;링크를 찾아 일일이 달아놓는 건 꽤 귀찮은 일이지만, 한편으로는 꽤 재미있는 일이기도 하다.&lt;/p&gt;
</description>
        <pubDate>Mon, 01 May 2017 07:33:10 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/05/01/jwp-08/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/05/01/jwp-08/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 07</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#일곱-번째-수업-이모저모&quot; id=&quot;markdown-toc-일곱-번째-수업-이모저모&quot;&gt;일곱 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상--삶과-프로그래밍&quot; id=&quot;markdown-toc-단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#감상--고흐의-편지를-읽고&quot; id=&quot;markdown-toc-감상--고흐의-편지를-읽고&quot;&gt;감상 : 고흐의 편지를 읽고&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#사족--레퍼런스-체크---인용된-반-고흐의-편지에-대해&quot; id=&quot;markdown-toc-사족--레퍼런스-체크---인용된-반-고흐의-편지에-대해&quot;&gt;사족 : 레퍼런스 체크 - 인용된 반 고흐의 편지에 대해&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#중간-점검&quot; id=&quot;markdown-toc-중간-점검&quot;&gt;중간 점검&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#중간-점검을-위한-실습-환경-설정&quot; id=&quot;markdown-toc-중간-점검을-위한-실습-환경-설정&quot;&gt;중간 점검을 위한 실습 환경 설정&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#요구사항&quot; id=&quot;markdown-toc-요구사항&quot;&gt;요구사항&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#메모&quot; id=&quot;markdown-toc-메모&quot;&gt;메모&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;일곱-번째-수업-이모저모&quot;&gt;일곱 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-24 19:00:00 +0900&lt;/code&gt;에 시작.
    &lt;ul&gt;
      &lt;li&gt;매 시간 정각에 시작하는 게 신기하다. 시계 보고 기다리고 있다가 00 초가 되면 바로 시작하시는 듯.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;매 수업 시작 전에 일찍 출석해서 책상 셋팅해주시는 분들게 감사 인사.&lt;/li&gt;
  &lt;li&gt;오늘은 중간 점검을 한다.
    &lt;ul&gt;
      &lt;li&gt;그동안 작성한 코드들을 사용하여 과제를 수행한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;목요일에는 과제에 대한 피드백을 하고, annotation 기반 MVC 프레임워크를 구현할 예정.&lt;/li&gt;
  &lt;li&gt;AJAX의 장단점에 대한 논의.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;빈센트 반 고흐가 테오에게 쓴 편지 중&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;열심히 노력하다가, 갑자기 나태해지고 잘 참다가 조급해지고, 희망에 부풀었다가 절망에 빠지는 일을 또 다시 반복하고 있다.&lt;br /&gt;
그래도 계속해서 노력하면 수채화를 더 잘 이해할 수 있겠지.&lt;br /&gt;
그게 쉬운 일이었다면 그 속에서 아무런 즐거움도 얻을 수 없었을 것이다.&lt;br /&gt;
그러니 계속해서 그림을 그려야겠다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;감상--고흐의-편지를-읽고&quot;&gt;감상 : 고흐의 편지를 읽고&lt;/h2&gt;

&lt;p&gt;고흐의 편지를 읽어보니 그가 반복적으로 찾아오는 절망 속에서 그림을 그렸음을 알 수 있다.
고흐는 살아있을 때 인정받은 사람이 아니다.
그는 삶의 막바지에 이르러 수채화를 이해하게 되었을까?&lt;/p&gt;

&lt;p&gt;돌이켜보면 나 또한 늘 불안에 빠져 있는 것 같다.
불안해서 매일 공부를 하고, 운동을 하고, 책을 읽는다.
특출난 사람들을 보면 고흐처럼 절망에 빠진다.
질투심보다 불안에 휩싸여 집으로 돌아와 홀린듯이 공부를 한다.
결과적으로 불안은 나의 저력일지도 모르겠다.
불안이 있기에 조금씩이라도 실력이 향상되고 더 나은 미래를 준비할 수 있다.&lt;/p&gt;

&lt;p&gt;늘상 불안을 안고 있는데도 그 못지 않은 행복을 느끼는 걸 보면
불안과 행복은 아마 다른 레이어에 걸쳐 있는 감정인 것 같다.
중첩이 가능하거나, 공존 가능한 심적 상태인 모양.&lt;/p&gt;

&lt;h2 id=&quot;사족--레퍼런스-체크---인용된-반-고흐의-편지에-대해&quot;&gt;사족 : 레퍼런스 체크 - 인용된 반 고흐의 편지에 대해&lt;/h2&gt;

&lt;p&gt;위의 인용된 번역된 반 고흐의 편지는 &lt;a href=&quot;https://books.google.co.kr/books?id=ydalAwAAQBAJ&amp;amp;lpg=PT60&amp;amp;ots=N3otvB4h94&amp;amp;dq=%EB%B0%98%20%EA%B3%A0%ED%9D%90%20%EA%B7%B8%EB%9E%98%EB%8F%84%20%EA%B3%84%EC%86%8D%ED%95%B4%EC%84%9C%20%EB%85%B8%EB%A0%A5%ED%95%98%EB%A9%B4%20%EC%88%98%EC%B1%84%ED%99%94%EB%A5%BC%20%EB%8D%94%20%EC%9E%98%20%EC%9D%B4%ED%95%B4%ED%95%A0%20%EC%88%98%20%EC%9E%88%EA%B2%A0%EC%A7%80&amp;amp;hl=ko&amp;amp;pg=PT60#v=onepage&amp;amp;q&amp;amp;f=false&quot;&gt;반 고흐, 영혼의 편지&lt;/a&gt;에 수록된 것이다. 그런데 갑자기 원문이 어떤지 궁금해졌으므로, &lt;a href=&quot;http://vangoghletters.org/&quot;&gt;vangoghletters.org&lt;/a&gt;에서 해당 편지를 찾아보았다.&lt;/p&gt;

&lt;p&gt;그리고 &lt;a href=&quot;http://vangoghletters.org/vg/letters/let199/letter.html&quot;&gt;해당 편지&lt;/a&gt;를 찾아냈다.&lt;/p&gt;

&lt;p&gt;링크로 들어가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;original text&lt;/code&gt;탭을 클릭하면 네덜란드어로 된 원문을 읽을 수 있고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translation&lt;/code&gt;탭을 클릭하면 영어 번역본을 읽을 수 있다.&lt;/p&gt;

&lt;p&gt;네덜란드의 반 고흐 박물관에서 운영하는 웹 사이트이므로 공신력을 인정받을 수 있는 번역이라 생각한다.&lt;/p&gt;

&lt;p&gt;그런데 영어로 번역된 문장은 [반 고흐, 영혼의 편지] 책에 수록된 것과 꽤 다른 느낌이었다.
아래의 한국어 번역은 내가 한 것이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Now I’m going through a similar period of struggle and despondency, of patience and impatience, of hope and desolation. But I must plod on and anyway, after a while I’ll understand more about making watercolours. If it were that easy, one wouldn’t take any pleasure in it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;이제 나는 투쟁과 낙담, 인내와 조바심, 희망과 황폐함의 시기를 겪고 있다. 그러나 꾸준히 내 길을 가다보면, 수채화를 더 잘 이해할 수 있겠지.
그게 쉬운 일이었다면 그 속에서 아무런 즐거움도 얻을 수 없었을 것이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그런데 다음 문장부터 내용이 다르다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;And it’s exactly the same with painting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;그리고 그것은 그림을 그리는 일과 완전히 똑같다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;반 고흐는 &quot;그러니 계속해서 그림을 그려야겠다&quot;고 하지 않았다. 고흐는 자신의 삶/공부 과정이 괴롭고 어렵지만 나름의 즐거움도 있다고 말하고 있고, 그것이 그림 그리는 과정과 상징적으로 일치한다고 말하고 있다.&lt;/p&gt;

&lt;p&gt;그렇다면 다음 문장에는 그런 말이 나올까? 안타깝게도 비슷한 말은 전혀 나오지 않았다.
날씨까지 나빠서 올 겨울엔 별로 즐겁지는 못했지만 삶을 즐기고 있고, 이제 자신의 스튜디오가 있어 너무 좋다고… 언제 한번 찾아와서 자신과 함께 커피나 마시자는 등의 이야기를 하고 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Moreover, the weather is bad, and this winter I haven’t yet gone out for pleasure. Still, I enjoy life and, in particular, having my own studio is too wonderful for words. When will you come and have coffee or tea with me? Soon I hope. You can stay here too, if necessary, that would be nice and companionable. And I even have flowers, and a couple of boxes of bulbs. And I’ve also acquired another ornament for my studio, I got a great bargain on some splendid woodcuts from The Graphic, some of them prints not of the clichés but of the blocks themselves. Just what I’ve been wanting for years.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;중간-점검&quot;&gt;중간 점검&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step7-johngrib&quot;&gt;GitHub&lt;/a&gt;에 올려두었다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;중간-점검을-위한-실습-환경-설정&quot;&gt;중간 점검을 위한 실습 환경 설정&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;자신의 계정으로 fork한 jwp-basic 프로젝트의 브랜치를 step7-self-check 으로 이동한다.&lt;/li&gt;
  &lt;li&gt;src/test/java 디렉토리의 next.WebServerLauncher의 main 메서드를 실행한 후 http://localhost:8080 으로 접근한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;요구사항&quot;&gt;요구사항&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;서버 초기화 과정을 설명할 것.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:8080&lt;/code&gt;으로 접근해서 질문 목록이 보이기까지 소스 코드의 호출 순서 및 흐름을 설명하라.&lt;/li&gt;
  &lt;li&gt;질문하기 기능을 구현한다.&lt;/li&gt;
  &lt;li&gt;로그인한 사용자만 질문이 가능하도록 수정한다.&lt;/li&gt;
  &lt;li&gt;상세보기 화면의 JSP에 하드코딩 된 부분을 JSTL과 EL을 사용하여 수정할 것.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CharacterEncodingFilter&lt;/code&gt;에 어노테이션 설정을 하여 한글 문제를 해결할 것.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShowController&lt;/code&gt;가 멀티 스레드 상황에서 문제가 발생하지 않도록 수정하고, 문제 원인을 설명한다.&lt;/li&gt;
  &lt;li&gt;답변을 추가하면 댓글 수가 1씩 증가하도록 수정한다.&lt;/li&gt;
  &lt;li&gt;QnA 전체 리스트를 JSON으로 돌려주는 api를 구현할 것.&lt;/li&gt;
  &lt;li&gt;상세보기 화면의 답변 삭제 기능을 AJAX로 구현할 것.&lt;/li&gt;
  &lt;li&gt;질문 수정 기능 구현할 것.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JdbcTemplate&lt;/code&gt;이 하나의 인스턴스로 작동되도록 수정한다.&lt;/li&gt;
  &lt;li&gt;질문 삭제 기능을 구현한다.&lt;/li&gt;
  &lt;li&gt;질문 삭제 기능 구현에 대한 단위 테스트를 작성한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;메모&quot;&gt;메모&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;* 94f6966 - [요구사항 12] JdbcTemplate Single Instance 유지하도록 수정 (11 hours ago)&amp;lt;John Grib&amp;gt;
* dd271b0 - [요구사항 11] 질문 수정 기능 구현(API만 구현) (11 hours ago)&amp;lt;John Grib&amp;gt;
* 3d3a7f9 - [요구사항 10] AJAX 답변 삭제 기능 구현 (12 hours ago)&amp;lt;John Grib&amp;gt;
* 561ae58 - [요구사항 9] JSON API 추가 : /api/qna/list (12 hours ago)&amp;lt;John Grib&amp;gt;
* 5e047bb - [요구사항 8] 답변을 달면 댓글 카운트가 증가하도록 수정 (13 hours ago)&amp;lt;John Grib&amp;gt;
* c70df2a - [요구사항 7] ShowController에서 발생 가능한 멀티 스레드 문제를 수정한다 (13 hours ago)&amp;lt;John Grib&amp;gt;
* a483e1d - [요구사항 6] CharacterEncodingFilter에 WebFilter annotation 적용 (13 hours ago)&amp;lt;John Grib&amp;gt;
* 2ff4dba - [요구사항 5] 상세보기 화면 답변 목록을 DB 조회하여 출력 (13 hours ago)&amp;lt;John Grib&amp;gt;
* a08eff7 - [요구사항 4] 로그인한 사용자만 질문이 가능하도록 수정한다. (13 hours ago)&amp;lt;John Grib&amp;gt;
* f3b24ee - [요구사항 3] 질문하기 기능 구현 (14 hours ago)&amp;lt;John Grib&amp;gt;
* c0cdc93 - 요구사항 1, 2 (14 hours ago)&amp;lt;John Grib&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;커밋 로그를 보니 대충 3 시간 정도 작업한 모양이다.&lt;/li&gt;
  &lt;li&gt;나는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JdbcTemplate&lt;/code&gt; 싱글 인스턴스 문제까지만 했다.&lt;/li&gt;
  &lt;li&gt;요구사항 11은 API만 구현했다. 프론트엔드 작업은 너무 번거롭다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-Ki7rZnr3DpctbqOtJQn&quot;&gt;삶과 프로그래밍: 빈센트 반 고흐&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9lXoEYVTp6w6Nkl3t/lessons/-Kh_ex_NZl4wAzOYTaJm&quot;&gt;중간 상태 점검&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-basic/tree/step7-self-check&quot;&gt;Step7 self-check&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;빈센트 반 고흐
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.vangoghmuseum.nl/&quot;&gt;Van Gogh Museum&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://vangoghletters.org/&quot;&gt;vangoghletters.org&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://vangoghletters.org/vg/letters/let199/letter.html&quot;&gt;To Theo van Gogh. The Hague, Sunday, 8 or Monday, 9 January 1882.&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://books.google.co.kr/books?id=ydalAwAAQBAJ&amp;amp;lpg=PT60&amp;amp;ots=N3otvB4h94&amp;amp;dq=%EB%B0%98%20%EA%B3%A0%ED%9D%90%20%EA%B7%B8%EB%9E%98%EB%8F%84%20%EA%B3%84%EC%86%8D%ED%95%B4%EC%84%9C%20%EB%85%B8%EB%A0%A5%ED%95%98%EB%A9%B4%20%EC%88%98%EC%B1%84%ED%99%94%EB%A5%BC%20%EB%8D%94%20%EC%9E%98%20%EC%9D%B4%ED%95%B4%ED%95%A0%20%EC%88%98%20%EC%9E%88%EA%B2%A0%EC%A7%80&amp;amp;hl=ko&amp;amp;pg=PT60#v=onepage&amp;amp;q&amp;amp;f=false&quot;&gt;반 고흐, 영혼의 편지: 습작에의 몰두&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 26 Apr 2017 21:49:43 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/26/jwp-07/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/26/jwp-07/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 06</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#여섯-번째-수업-이모저모&quot; id=&quot;markdown-toc-여섯-번째-수업-이모저모&quot;&gt;여섯 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상--삶과-프로그래밍&quot; id=&quot;markdown-toc-단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#나는-행복한가&quot; id=&quot;markdown-toc-나는-행복한가&quot;&gt;나는 행복한가?&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#jdbc-라이브러리-구현&quot; id=&quot;markdown-toc-jdbc-라이브러리-구현&quot;&gt;JDBC 라이브러리 구현&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#메모&quot; id=&quot;markdown-toc-메모&quot;&gt;메모&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;여섯-번째-수업-이모저모&quot;&gt;여섯 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-20 19:00:00 +0900&lt;/code&gt;에 시작.&lt;/li&gt;
  &lt;li&gt;오늘은 MVC 패턴을 공부하고, JDBC 라이브러리를 만들어 보도록 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상--삶과-프로그래밍&quot;&gt;단상 : 삶과 프로그래밍&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;책 소개 : &lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?barcode=9788995540213&quot;&gt;이너 게임&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;행복하게 일하며 회사 다니는 사람에게는 필요 없는 책이라 한다.&lt;/li&gt;
      &lt;li&gt;내게는 필요 없는 책인듯.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;나는-행복한가&quot;&gt;나는 행복한가?&lt;/h2&gt;

&lt;p&gt;나는 행복한 활동에 대해 두 가지 조건이 있다고 생각한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;불행−− : 불행을 제거할 수 있어야 한다.&lt;/li&gt;
  &lt;li&gt;행복++ : 행복을 증가시켜야 한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;나는 행복한가? 나는 행복하다. 단언할 수 있다. 적어도 글을 쓰고 있는 지금은 그렇게 생각한다.
그리고 이 행복에 프로그래밍이 적지 않게 좋은 영향을 주고 있다고도 생각한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;프로그래밍은 내 삶에 발생했던 적지 않은 불행들을 간접적으로 제거해 주었다.
    &lt;ul&gt;
      &lt;li&gt;이제는 월급이 꼬박꼬박 나온다.&lt;/li&gt;
      &lt;li&gt;이전의 다른 직업들을 가졌을 때는 삶이 너무 힘들었다.&lt;/li&gt;
      &lt;li&gt;앉아서 하는 일이 하고 싶었다. -&amp;gt; 앉아서 프로그래밍을 한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;프로그래밍을 하면 행복한가?
    &lt;ul&gt;
      &lt;li&gt;괴로울 때도 종종 있지만, 전체적으로 즐겁고 흥미진진한 나날이라 생각한다.&lt;/li&gt;
      &lt;li&gt;회사 일 외에도 개인 프로젝트로 만들고 싶은 것들을 만들어내는 기쁨이 있다.&lt;/li&gt;
      &lt;li&gt;다른 데스크 잡에 비해 엄청나게 재미있는 편이어서, 회사에서 일만 하고 있어도 시간 가는 줄 모를 정도로 푹 빠져 있는 경우가 많다.&lt;/li&gt;
      &lt;li&gt;프로그래밍 공부는 많이 재미있는 편이다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;jdbc-라이브러리-구현&quot;&gt;JDBC 라이브러리 구현&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step2-johngrib&quot;&gt;GitHub&lt;/a&gt;에 올려 두었다.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/jwp-basic/pull/5&quot;&gt;Pull Request&lt;/a&gt;도 날려 두었다.&lt;/li&gt;
      &lt;li&gt;작업한 결과 마지막에 나온 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UserDao.java&lt;/code&gt;의 내용은 아래와 같다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserDao&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;INSERT INTO USERS VALUES (${userId}, ${password}, ${name}, ${email})&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JdbcTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;UPDATE USERS SET password = ${password}, name = ${name}, email = ${email} WHERE userId = ${userId}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JdbcTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SELECT userid, password, name, email FROM USERS&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JdbcTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findByUserId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SELECT userId, password, name, email FROM USERS WHERE userid=${userId}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JdbcTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;selectOne&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;학습용으로 짠 거라 허술한 점이 많다. 가령, 이걸 진짜로 쓰려면 Injection 방어 코드를 추가해 주어야 한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reflection&lt;/code&gt;을 사용해서 객체의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt;메서드 호출로 자동으로 값이 들어가도록 해 주었다.
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Statement&lt;/code&gt;가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt;를 사용하는 방식이 마음에 안 들었기 때문. 혹시라도 순서가 어긋나면 와장창 깨질 수 있다는 게 마음에 들지 않는다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;재미있게 작업한 건 좋았는데, 하다보니 과잉이 좀 있었다. 오버 엔지니어링 스멜.&lt;/li&gt;
  &lt;li&gt;아직까지 내게 Java는 너무 답답하고 수다스러운 언어다. 뭔가 하려면 너무 많이 써야 한다. 물론 Java6 쓰던 때와 Java8을 쓰는 지금을 감히 비교할 수는 없지만.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;메모&quot;&gt;메모&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;지난 수업들 중 가장 재미있는 시간이었다.&lt;/li&gt;
  &lt;li&gt;JDBC 라이브러리 구현은 이전에 해 보려는 마음을 먹었다가 실천하지 못했던 주제였는데, 이번 기회에 시도하게 되었다.
    &lt;ul&gt;
      &lt;li&gt;약 2 시간 동안 느낀 점이 많았다.&lt;/li&gt;
      &lt;li&gt;미진한 실천력에 대해 반성했다.&lt;/li&gt;
      &lt;li&gt;보통 강좌라 하면 라이브러리 사용법을 소개하거나 하는데, 박재성 교수님의 수업은 라이브러리를 함께 만들어가는 방식이라 좀 더 깊이 있게 공부할 수 있는 것 같다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;템플릿 메소드 패턴은 예전에 게임 만들 때 꽤 많이 썼었는데, 웹 개발 중에는 남이 만든 라이브러리만 가져다 쓰다 보니 쓸 일이 거의 없었던 것 같다.&lt;/li&gt;
  &lt;li&gt;DB는 H2를 사용했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ # H2 DB 백그라운드 구동. 구동이 끝나면 웹 브라우저에서 관리 콘솔이 열린다.
$ java -jar h2-1.3.167.jar &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-Ki7rZnr3DpctbqOtJQn&quot;&gt;삶과 프로그래밍 - 책 소개: 이너 게임&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9l9BNDgvymNo6IxDs/lessons/-KgrP2wkZA3uUvzWxiAs&quot;&gt;JDBC 라이브러리 실습&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Template_method_pattern&quot;&gt;Template method pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 22 Apr 2017 23:36:10 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/22/jwp-06/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/22/jwp-06/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 05</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#다섯-번째-수업-이모저모&quot; id=&quot;markdown-toc-다섯-번째-수업-이모저모&quot;&gt;다섯 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#준비물&quot; id=&quot;markdown-toc-준비물&quot;&gt;준비물&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#과제-구현&quot; id=&quot;markdown-toc-과제-구현&quot;&gt;과제 구현&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상--객체지향-연습-방법은&quot; id=&quot;markdown-toc-단상--객체지향-연습-방법은&quot;&gt;단상 : 객체지향 연습 방법은?&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#메모--내-생각&quot; id=&quot;markdown-toc-메모--내-생각&quot;&gt;메모 : 내 생각&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;다섯-번째-수업-이모저모&quot;&gt;다섯 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-17 19:00:00 +0900&lt;/code&gt;에 시작.
    &lt;ul&gt;
      &lt;li&gt;오늘은 리팩토링 후 Servlet, MVC 구현 순으로 학습.&lt;/li&gt;
      &lt;li&gt;앞으로 2주간은 MVC + JDBC + AJAX 구현 실습이 예정되어 있다.&lt;/li&gt;
      &lt;li&gt;이후로는 프레임워크를 구현하면서 Spring 공부할 준비를 한다.&lt;/li&gt;
      &lt;li&gt;JSP 수업은 패스.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;준비물&quot;&gt;준비물&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;오늘 수업은 준비물이 있었다.
    &lt;ul&gt;
      &lt;li&gt;https://github.com/slipp/jwp-basic 저장소를 자신의 계정으로 fork한다.&lt;/li&gt;
      &lt;li&gt;fork한 jwp-basic 저장소를 로컬 PC로 clone한 후 master 브랜치를 step0-getting-started 브랜치로 변경한다.&lt;/li&gt;
      &lt;li&gt;IntelliJ IDEA에서 maven 프로젝트로 import한다.&lt;/li&gt;
      &lt;li&gt;src/test/java 디렉토리의 next.WebServerLauncher를 실행한 후 브라우저에서 http://localhost:8080 접속해 질문/답변 게시판 서비스 화면이 나타나는지 확인한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;과제-구현&quot;&gt;과제 구현&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/jwp-basic/tree/step1-johngrib&quot;&gt;Github Repository&lt;/a&gt;에 올려두었다.&lt;/li&gt;
  &lt;li&gt;HTTP 웹 서버 구현할 때 만들었던 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Annotation&lt;/code&gt;과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReflectionUtil&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ControllerRegister&lt;/code&gt;등을 그대로 복붙… 아니 재활용해서 완료했다.&lt;/li&gt;
  &lt;li&gt;차이가 있다면: 지난번에는 Controller &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interface&lt;/code&gt;를 작성한 반면, 이번에는 Controller를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abstract class&lt;/code&gt;로 작성했다. forward method를 분리하기 위한 목적.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상--객체지향-연습-방법은&quot;&gt;단상 : 객체지향 연습 방법은?&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;게임을 만들어 보기&lt;/li&gt;
  &lt;li&gt;마음 맞는 사람들과 서로 Code 리뷰&lt;/li&gt;
  &lt;li&gt;기타 등등…&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;메모--내-생각&quot;&gt;메모 : 내 생각&lt;/h2&gt;

&lt;p&gt;이건 딱히 객체지향을 위한 방법은 아니지만 객체지향 연습에도 도움이 되는 방법이라 생각해서 메모한다.&lt;/p&gt;

&lt;p&gt;계속해서 새로운 프로그램을 개발해보되, 같은 프로그램을 재개발하는 경험이 꽤 효과적이었던 것 같다.
열 번 스무 번 반복 개발할 필요까지는 없고, 똑같은 프로그램을 한 번 더 개발해보는 정도가 좋았다. 세 번째부터는 괴로운 느낌이 든다.&lt;/p&gt;

&lt;p&gt;요약하자면 다음과 같은 무간지옥 사이클이라 할 수 있다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;개발&lt;/li&gt;
  &lt;li&gt;재개발&lt;/li&gt;
  &lt;li&gt;회고, 리뷰 : 교훈을 얻는다.&lt;/li&gt;
  &lt;li&gt;다른 프로그램 개발 계획을 세운다.&lt;/li&gt;
  &lt;li&gt;1로 돌아간다.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;다음 프로그램에서 사용할만한 코드가 있다면 라이브러리화해서 조금이나마 무간지옥을 편하게 한다.&lt;/li&gt;
  &lt;li&gt;망했다 싶으면 다 지워도 된다. 업무라면 큰일나겠지만 이건 연습이니까. 게다가 git도 있고, 경험도 남아 있다. Fred Brooks도 어차피 언젠간 버리게 될 테니까 한 번은 버릴 마음을 갖고 코딩하라고 했었지 아마.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;강의 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-KgqHPfpV1xrdi1_T9ne/lessons/-KhesAfA5zcP22Y7bZOZ&quot;&gt;객체지향 연습 방법은?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9l1h-u-6DhIWzcnjo/lessons/-KgDx_w1lA2CAXtHFpxE&quot;&gt;HTTP 웹 서버와 Servlet&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 17 Apr 2017 15:20:00 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/17/jwp-05/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/17/jwp-05/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 04</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#네-번째-수업-이모저모&quot; id=&quot;markdown-toc-네-번째-수업-이모저모&quot;&gt;네 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;네-번째-수업-이모저모&quot;&gt;네 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-13 19:00:00 +0900&lt;/code&gt;에 시작.
    &lt;ul&gt;
      &lt;li&gt;이론 수업, 리팩토링 라이브 코딩, AWS 배포 실습 순으로 진행되었다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이론 수업
    &lt;ul&gt;
      &lt;li&gt;HTTP Status Code에 대하여&lt;/li&gt;
      &lt;li&gt;302와 200의 차이점은?&lt;/li&gt;
      &lt;li&gt;Cookie와 Session의 차이점은?&lt;/li&gt;
      &lt;li&gt;Session 방식의 문제점은?&lt;/li&gt;
      &lt;li&gt;Session 방식 문제점의 해결책은?
        &lt;ul&gt;
          &lt;li&gt;Sticky Session, Session Storage, Session Clustering, HA Proxy 사용 등등.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;리팩토링 시범&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;AWS 배포 실습
    &lt;ul&gt;
      &lt;li&gt;AWS EC2 인스턴스 생성해서 접속까지.
        &lt;ul&gt;
          &lt;li&gt;나는 수업 전에 Tmux에서 접속해놓고 수업 중 Tmux로 재접속해서 편하게 작업했다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Java, Maven, Git 설치.&lt;/li&gt;
      &lt;li&gt;AWS Security Group 설정 후, 웹 페이지 열리나 확인.&lt;/li&gt;
      &lt;li&gt;자동 배포 쉘 스크립트 작성.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;강의 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9koDWsc8jpIgwbgR5/lessons/-KfFQQPBEByK_-XOYbD5&quot;&gt;AWS 원격 서버에 배포&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 13 Apr 2017 12:15:32 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/13/jwp-04/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/13/jwp-04/</guid>
        
        <category>study jwp aws</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 03</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#세-번째-수업-이모저모&quot; id=&quot;markdown-toc-세-번째-수업-이모저모&quot;&gt;세 번째 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#단상--좋은-개발자란&quot; id=&quot;markdown-toc-단상--좋은-개발자란&quot;&gt;단상 : 좋은 개발자란?&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#나의-생각--좋은-개발자란&quot; id=&quot;markdown-toc-나의-생각--좋은-개발자란&quot;&gt;나의 생각 : 좋은 개발자란?&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#좋은-개발자의-이데아&quot; id=&quot;markdown-toc-좋은-개발자의-이데아&quot;&gt;좋은 개발자의 이데아&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#너무-뛰어난-개발자의-딜레마&quot; id=&quot;markdown-toc-너무-뛰어난-개발자의-딜레마&quot;&gt;너무 뛰어난 개발자의 딜레마&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#그-외-생각들-메모&quot; id=&quot;markdown-toc-그-외-생각들-메모&quot;&gt;그 외 생각들 메모&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;세-번째-수업-이모저모&quot;&gt;세 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-10 19:00:00 +0900&lt;/code&gt;에 시작.
    &lt;ul&gt;
      &lt;li&gt;이번에는 이론 수업, 실습 순으로 진행되었다.&lt;/li&gt;
      &lt;li&gt;실습 시간에 요구사항을 마저 구현하고, 리팩토링도 하는 것이 목표.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;편안하고 자유로운 분위기의 수업을 지향.
    &lt;ul&gt;
      &lt;li&gt;예 : 다 한 사람은 집에 가도 된다.&lt;/li&gt;
      &lt;li&gt;나는 숙제로 요구사항을 다 구현해 왔고 리팩토링도 했으므로, 교수님께 구현한 내용을 보여드리고 실습 생략하고 집에 갔음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이론 강의
    &lt;ul&gt;
      &lt;li&gt;HTTP 기본, OSI 7 계층, 콘텐츠 효율성 최적화, 보안 등.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;단상--좋은-개발자란&quot;&gt;단상 : 좋은 개발자란?&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;박재성 교수님과 다른 사람들의 의견을 들어볼 수 있는 시간이었다.&lt;/li&gt;
  &lt;li&gt;유명한 책들을 봐도 그렇고, 좋은 개발자의 유형은 거의 뚜렷한 것 같다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;나의-생각--좋은-개발자란&quot;&gt;나의 생각 : 좋은 개발자란?&lt;/h2&gt;

&lt;h3 id=&quot;좋은-개발자의-이데아&quot;&gt;좋은 개발자의 이데아&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;&quot;행복한 가정은 모두 모습이 비슷하고, 불행한 가정은 모두 제각각의 불행을 안고 있다.&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;안나 카레니나&lt;/strong&gt;의 첫 문장이다. (레프 톨스토이, 안진희 역. [안나 카레니나] 1권, 민음사 2009)&lt;/p&gt;

&lt;p&gt;좋은 개발자에 대한 논의도 이와 비슷하다고 생각한다.&lt;br /&gt;
좋은 개발자들은 대개 비슷한 특성을 갖고 있을 것으로 &lt;strong&gt;예견&lt;/strong&gt;된다.&lt;br /&gt;
그러나 보통 &lt;strong&gt;좋은 개발자와 거리가 좀 있는 개발자&lt;/strong&gt;들은 다 나름의 독특한 이유들이 있다.&lt;br /&gt;
코딩을 못한다거나, 성격이 나쁘다거나, 공부를 안한다거나, …&lt;/p&gt;

&lt;h3 id=&quot;너무-뛰어난-개발자의-딜레마&quot;&gt;너무 뛰어난 개발자의 딜레마&lt;/h3&gt;

&lt;p&gt;회사에서 일하는 개발자의 조건에 한정하여 고용주 관점에서 생각해보면 어떨까.
좋은 개발자는 1인분 이상의 일을 하는 개발자일까?
회사의 모든 것을 알고 모든 업무에 지원이 가능한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static public&lt;/code&gt; 개발자는 어떨까?&lt;/p&gt;

&lt;p&gt;제럴드 와인버그는 &lt;strong&gt;프로그래밍 심리학&lt;/strong&gt;에서 다음과 같이 썼다.&lt;br /&gt;
(제럴드 와인버그, 조상민 역. [프로그래밍 심리학] 6장. 프로그래밍 프로젝트, 인사이트 2008)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;절대 없어서는 안 될 프로그래머가 있다면, 한시라도 빨리 그를 프로젝트에서 제거하라.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;의미는 뚜렷하다. 대체 불가능한 프로그래머는 고용주와 관리자에게 리스크가 된다.
뛰어난 개발자이면서 동시에 핵심 인력인 사람은 회사의 대들보가 되기 마련이지만
어느날 갑자기 그가 예상치 못한 중병에 걸려 쓰러진다면? 교통사고를 당한다면?
회사는 위기에 처하게 된다.&lt;/p&gt;

&lt;p&gt;따라서 고용주 입장만 고려했을 때&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;리스크 최소화를 위해 개발자는 모듈화 되어야 한다.&lt;/li&gt;
  &lt;li&gt;개별적으로 뛰어나지만 대체 가능한 인력들로 팀을 구성해야 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;소프트웨어 개발과 통하는 점이 있다는 생각이 든다.
소프트웨어만 리팩토링이 필요한 것이 아니다.
회사의 많은 인력들이 한 사람에게 의존하고 있다면,
좋지 못한 소프트웨어에서 나는 나쁜 냄새가 조직에서도 발생한다고 말할 수 있을 것 같다.&lt;/p&gt;

&lt;h3 id=&quot;그-외-생각들-메모&quot;&gt;그 외 생각들 메모&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;개발자는 훌륭한 프로그래밍 원칙을 삶에서도 실천하는 사람이 되어야 할까?
    &lt;ul&gt;
      &lt;li&gt;YES. 나는 일관성을 중요하게 생각한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;한 사람의 개발자의 POWER가 과거보다 줄어든 것은 사실이다.
    &lt;ul&gt;
      &lt;li&gt;그렇다면 현재 시점에서는 좋은 개발자보다 좋은 팀에 대한 논의가 좀 더 의미있지 않을까?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html&quot;&gt;In Introduction to HTTP Basics&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Transport_Layer_Security&quot;&gt;Transport Layer Security&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/OSI_model&quot;&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;강의 자료
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9koDWsc8jpIgwbgR5/lessons/-KfB3f2A8L1WBm542DxB&quot;&gt;웹 서버 구현에 따른 피드백&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9koDWsc8jpIgwbgR5/lessons/-Kh6E1kW6zxxKIX0MPzo&quot;&gt;HTTP 학습에 따른 활용&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/&quot;&gt;콘텐츠 효율성 최적화&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사이트 성능 분석 도구
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://developers.google.com/speed/pagespeed/?hl=ko-KR&amp;amp;utm_source=PSI&amp;amp;utm_medium=incoming-link&amp;amp;utm_campaign=PSI&quot;&gt;PageSpeed Tools : 사이트 성능 분석&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://yslow.org/&quot;&gt;YSlow&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 10 Apr 2017 22:47:18 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/10/jwp-03/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/10/jwp-03/</guid>
        
        <category>study jwp 개발자 프로그래밍-심리학 Gerald-Weinberg</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 02</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#두-번째-수업-이모저모&quot; id=&quot;markdown-toc-두-번째-수업-이모저모&quot;&gt;두 번째 수업 이모저모&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#객체지향-생활-체조&quot; id=&quot;markdown-toc-객체지향-생활-체조&quot;&gt;객체지향 생활 체조&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#for-루프를-쪼개야-할까&quot; id=&quot;markdown-toc-for-루프를-쪼개야-할까&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; 루프를 쪼개야 할까&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#코딩-실습-및-과제--http-웹-서버-구현&quot; id=&quot;markdown-toc-코딩-실습-및-과제--http-웹-서버-구현&quot;&gt;코딩 실습 및 과제 : HTTP 웹 서버 구현&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#요구사항&quot; id=&quot;markdown-toc-요구사항&quot;&gt;요구사항&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#과제-후기&quot; id=&quot;markdown-toc-과제-후기&quot;&gt;과제 후기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;두-번째-수업-이모저모&quot;&gt;두 번째 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-06 19:00:00 +0900&lt;/code&gt;에 시작.
    &lt;ul&gt;
      &lt;li&gt;오늘부터 다음 주 목요일 &lt;strong&gt;2017-04-13&lt;/strong&gt; 까지는 HTTP Web Server 개발 실습을 한다.&lt;/li&gt;
      &lt;li&gt;그 다음주 월요일인 &lt;strong&gt;2017-04-17&lt;/strong&gt; 에는 교수님의 라이브 코딩이 예정되어 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;단상 : 프로그래밍 연습 어떻게 할 것인가?
    &lt;ul&gt;
      &lt;li&gt;작은 프로그램을 반복적으로, 다양하게 구현해 보도록 한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;교수님 라이브 코딩 및 TDD 시범.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;TDD 실천법에 대한 논의 및 Q &amp;amp; A.
    &lt;ul&gt;
      &lt;li&gt;TDD 경험에 대한 발표.&lt;/li&gt;
      &lt;li&gt;TDD를 하려면 객체지향 철학을 잘 활용해야 한다.&lt;/li&gt;
      &lt;li&gt;로직 위주로 가도록 한다.&lt;/li&gt;
      &lt;li&gt;과도한 테스트 코드는 지양한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;마틴 파울러와 직원들이 지은 책 &lt;a href=&quot;http://wikibook.co.kr/thoughtworks-anthology/&quot;&gt;The ThoughtWorks Anthology&lt;/a&gt;에 나온 &lt;strong&gt;객체지향 생활 체조&lt;/strong&gt; 소개.
    &lt;ul&gt;
      &lt;li&gt;좋아하는 책이었기에 반가웠다.&lt;/li&gt;
      &lt;li&gt;집에 돌아와 &lt;strong&gt;객체지향 생활 체조&lt;/strong&gt; 챕터를 다시 읽어 보았다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;객체지향-생활-체조&quot;&gt;객체지향 생활 체조&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;한 메서드에 오직 한 단계의 들여쓰기만 한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; 예약어&lt;sub&gt;keyword&lt;/sub&gt;를 쓰지 않는다.&lt;/li&gt;
  &lt;li&gt;모든 원시값과 문자열을 포장&lt;sub&gt;wrap&lt;/sub&gt;한다.&lt;/li&gt;
  &lt;li&gt;한 줄에 점을 하나만 찍는다.&lt;/li&gt;
  &lt;li&gt;줄여쓰지 않는다(축약금지).&lt;/li&gt;
  &lt;li&gt;모든 엔티티&lt;sub&gt;entity&lt;/sub&gt;를 작게 유지한다.&lt;/li&gt;
  &lt;li&gt;2개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.&lt;/li&gt;
  &lt;li&gt;제일 클래스&lt;sub&gt;first-class&lt;/sub&gt; 콜렉션을 쓴다.&lt;/li&gt;
  &lt;li&gt;게터&lt;sub&gt;getter&lt;/sub&gt;/세터&lt;sub&gt;setter&lt;/sub&gt;/프로퍼티&lt;sub&gt;property&lt;/sub&gt;를 쓰지 않는다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;꽤 깐깐한 체조 같지만, 조금만 생각해보면 개발자의 멍청한 실수를 최대한 예방하는 좋은 습관들임을 알 수 있다.&lt;/p&gt;

&lt;p&gt;문득 스티브 맥코넬이 &lt;em&gt;Code Complete&lt;/em&gt; 에서 한 말이 생각났다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;최종 목표는 한번에 생각해야 하는 프로그램의 양을 최소화하는 것이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;for-루프를-쪼개야-할까&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; 루프를 쪼개야 할까&lt;/h2&gt;
&lt;p&gt;Q &amp;amp; A 시간에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop에 대한 이야기가 나왔다.&lt;/p&gt;

&lt;p&gt;두 가지 일을 하는 하나의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; loop를 교수님이 한 가지 일을 하는 두 개의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt;루프로 쪼갰는데 누군가 이런 말을 했다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&quot;for 루프가 두 번 돌아서 기분이 나쁩니다.&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;지극히 정상적이고 상식적인 반응이다. 그러나 이것은 반론 불가능한 도그마일까? 복잡한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; 루프는 버그의 온상이다. 새벽 두 시에 끝이 안 보이는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; 루프를 투덜대며 분해해 본 경험을 누구나 갖고 있지 않나? 나는 약 3년 전, Scala를 사용하기 시작했을 무렵부터 루프를 쪼개는 습관을 갖게 되었는데 나 뿐만 아니라 주위의 동료들이 (아주 미묘한 차이이긴 하지만) 조금씩 더 행복해진 놀라운 경험이 있다.&lt;/p&gt;

&lt;p&gt;찾아보니 이 건에 대해서도 스티브 맥코넬이 &lt;em&gt;Code Complete&lt;/em&gt; 에 남겨 놓은 말이 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;루프가 한번에 두 가지 일을 하기 위해서 사용될 수 있다는 사실만으로는 두 가지 기능을 동시에 수행해도 된다는 것을 정당화하지 못한다. 하나의 루프는 반드시 한 가지 일만 수행하고 그 작업을 제대로 수행해야 한다는 면에서, 루틴과 같아야 한다. 만약 루프 하나만으로도 충분한 코드에 두 개의 루프를 사용하는 것이 비효율적인 것처럼 보인다면, 두 개의 루프로 코드를 작성한 후, 효율성을 위해서 결합될 수 있다는 것을 주석으로 작성하여, 두 개의 루프를 하나로 통합하기 전에 벤치마크 결과가 해당 코드 섹션에서 성능 문제가 발생한다는 것을 보고할 때까지 기다리도록 한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;생각해 볼 것들.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(2n)&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(n)&lt;/code&gt;의 관계.&lt;/li&gt;
  &lt;li&gt;런타임 시간보다 개발/유지보수 시간을 중요하시는 관점.
    &lt;ul&gt;
      &lt;li&gt;산업의 유형에 따라 선호하는 언어가 다른 이유하고도 관련이 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;코딩-실습-및-과제--http-웹-서버-구현&quot;&gt;코딩 실습 및 과제 : HTTP 웹 서버 구현&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;이 작업은 박재성 교수님의 &lt;a href=&quot;https://github.com/slipp/web-application-server&quot;&gt;web-application-server&lt;/a&gt;를 fork하여 수행하도록 한다.&lt;/li&gt;
  &lt;li&gt;다음 시간까지 최소한 요구사항 5 까지는 작업해 올 것.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;요구사항&quot;&gt;요구사항&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;요구사항 1 : 웹서버 구색 갖추기
    &lt;ul&gt;
      &lt;li&gt;http://localhost:8080/index.html 로 접속했을 때 webapp 디렉토리의 index.html 파일을 읽어 클라이언트에 응답한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;요구사항 2 : 회원가입 구현.&lt;/li&gt;
  &lt;li&gt;요구사항 3 : 회원가입 구현기능을 post 방식으로 변경하기.&lt;/li&gt;
  &lt;li&gt;요구사항 4 : 회원 가입을 완료하면 /index.html로 이동하게 한다.&lt;/li&gt;
  &lt;li&gt;요구사항 5 : 로그인 구현, 로그인 성공/실패시 페이지 리다이렉트.&lt;/li&gt;
  &lt;li&gt;요구사항 6 : 로그인 상태에서 /user/list로 접근하면 사용자 목록 출력.&lt;/li&gt;
  &lt;li&gt;요구사항 7 : css 지원.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;과제-후기&quot;&gt;과제 후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;만들다보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Annotation&lt;/code&gt; 기반의 Controller Interface 형태의 웹 서버를 구현하게 되었다.&lt;/li&gt;
  &lt;li&gt;평소 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Annotation&lt;/code&gt;을 자바 진영의 일종의 &lt;strong&gt;흑마술&lt;/strong&gt; 이라고 생각해서 별로 좋아하지 않았는데, 직접 뭔가 만드는 데 사용해보니 엄청 편리하다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Annotation&lt;/code&gt;에 대한 호의가 무럭무럭.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;나는 immutable 개념을 좋아해서 가능한 한 변수는 사용하지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;final&lt;/code&gt; 상수를 사용하며, 중요 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt;과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unmodifiable&lt;/code&gt;을 씌워줬다. Java 문법상 꼭 키워드를 하나씩 더 타이핑해야 해서 너무 귀찮았다. Java의 문법은 내 언어 습관상으로는 몹시 수다스럽다. Vim이 아니라 IntelliJ의 조악한 Vim 플러그인으로 코딩을 했더니 손가락이 얼얼하다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/web-application-server/tree/02-http&quot;&gt;Github repository&lt;/a&gt;에 올려두었다.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/web-application-server/blob/02-http/src/main/java/webserver/RequestHandler.java&quot;&gt;RequestHandler&lt;/a&gt; : 이거 리팩토링하느라 걸린 시간이 전체 개발 시간의 80% 는 되는 것 같다.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/web-application-server/blob/02-http/src/main/java/controller/UserLogin.java&quot;&gt;UserLogin 클래스&lt;/a&gt; : Spring 처럼 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Controller&lt;/code&gt; 어노테이션을 만들어 적용해 보았다. 재밌었다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/slipp/web-application-server&quot;&gt;web-application-server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr/-Kf9koDWsc8jpIgwbgR5/lessons&quot;&gt;강의 자료&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections&quot;&gt;MDN - Http Redirections&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies&quot;&gt;MDN - Http Cookies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 08 Apr 2017 21:29:47 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/08/jwp-02/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/08/jwp-02/</guid>
        
        <category>study jwp 소트웍스-앤솔러지 martin-fowler oop</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 01</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#첫-수업-이모저모&quot; id=&quot;markdown-toc-첫-수업-이모저모&quot;&gt;첫 수업 이모저모&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#첫-코딩-과제--문자열-계산기&quot; id=&quot;markdown-toc-첫-코딩-과제--문자열-계산기&quot;&gt;첫 코딩 과제 : 문자열 계산기&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#요구사항&quot; id=&quot;markdown-toc-요구사항&quot;&gt;요구사항&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#프로그래밍-요구사항&quot; id=&quot;markdown-toc-프로그래밍-요구사항&quot;&gt;프로그래밍 요구사항&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#추가-요구사항&quot; id=&quot;markdown-toc-추가-요구사항&quot;&gt;추가 요구사항&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#첫-코딩-과제-후기&quot; id=&quot;markdown-toc-첫-코딩-과제-후기&quot;&gt;첫 코딩 과제 후기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;첫-수업-이모저모&quot;&gt;첫 수업 이모저모&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;첫 수업은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2017-04-03 19:00:00 +0900&lt;/code&gt;에 시작됐다.&lt;/li&gt;
  &lt;li&gt;회사의 동료 개발자들이 30명 정도 모여 수업을 듣는다.
    &lt;ul&gt;
      &lt;li&gt;수강생들의 경력/기술 스택이 다양하기 때문에 건의사항을 제시하면 바로 반영될 것이라 한다.&lt;/li&gt;
      &lt;li&gt;수업 시간은 19시~22시. 꽤 늦은 시간에 수업이 끝난다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;단위 테스트와 리팩토링 논의.
    &lt;ul&gt;
      &lt;li&gt;TDD 방식은 개인적으로 좋아하고 즐기는 편이라 논의가 나와 즐거웠다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;집에 가는 길에 박재성 교수님을 지하철에서 뵌 것 같은데 긴가민가 하다가 인사를 못했다!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;첫-코딩-과제--문자열-계산기&quot;&gt;첫 코딩 과제 : 문자열 계산기&lt;/h1&gt;

&lt;h2 id=&quot;요구사항&quot;&gt;요구사항&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환 (예: “” =&amp;gt; 0, &quot;1,2&quot; =&amp;gt; 3, &quot;1,2,3&quot; =&amp;gt; 6, “1,2:3” =&amp;gt; 6)&lt;/li&gt;
  &lt;li&gt;앞의 기본 구분자(쉼표, 콜론)외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 “//”와 “\n” 사이에 위치하는 문자를 커스텀 구분자로 사용한다. 예를 들어 “//;\n1;2;3”과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.&lt;/li&gt;
  &lt;li&gt;문자열 계산기에 숫자 이외의 값 또는 음수를 전달하는 경우 RuntimeException 예외를 throw한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;프로그래밍-요구사항&quot;&gt;프로그래밍 요구사항&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;indent(들여쓰기) depth를 2단계에서 1단계로 줄여라.&lt;/li&gt;
  &lt;li&gt;depth의 경우 if문을 사용하는 경우 1단계의 depth가 증가한다. if문 안에 while문을 사용한다면 depth가 2단계가 된다.&lt;/li&gt;
  &lt;li&gt;else를 사용하지 마라.&lt;/li&gt;
  &lt;li&gt;method가 한 가지 일만 하도록 최대한 작게 만들어라.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;추가-요구사항&quot;&gt;추가 요구사항&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;앞의 요구사항을 모두 만족하도록 기능을 구현할 경우 다음 요구사항을 추가적으로 도전해 본다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;숫자 값을 위해 int과 같은 primitive type을 직접 사용하지 말고 자바 객체를 생성해 구현해 본다.&lt;/li&gt;
  &lt;li&gt;문자열을 split하는 규칙이 현재는 기본 구분자와 custom 구분자 두 가지가 있다. 앞으로 문자열을 split하는 규칙이 계속해서 추가될 것으로 예상한다. 규칙이 추가되더라도 영향을 최소화하면서 확장 가능하도록 구현한다.&lt;/li&gt;
  &lt;li&gt;java 8에 추가된 람다를 활용해 위 요구사항을 구현해 본다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;첫-코딩-과제-후기&quot;&gt;첫 코딩 과제 후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;내 구현 내용은 &lt;a href=&quot;https://github.com/johngrib/jwp_calculator&quot;&gt;Github repository&lt;/a&gt;에 올려두었다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt;를 쓰지 않고, 가급적이면 인덴트를 적은 depth로 유지하는 것은 내가 선호하는 스타일이기도 하다.&lt;/li&gt;
  &lt;li&gt;패턴 생각하지 않고 직감에 따라 찬찬히 구현했는데 꽤 즐거웠다.&lt;/li&gt;
  &lt;li&gt;규칙 추가와 변경 가능성을 가장 중요한 조건으로 자의적으로 판단하고 작업했다.&lt;/li&gt;
  &lt;li&gt;추가 요구사항 중 primitive type을 사용하지 않는 건 pass 했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://firebasestorage.googleapis.com/v0/b/nextstep-real.appspot.com/o/lesson-attachments%2F-KgqHzXq92AfQVxeZor5%2F%EA%B3%BC%EC%A0%95%20%EC%86%8C%EA%B0%9C.pdf?alt=media&amp;amp;token=23006ea0-85e7-479c-86a8-770d499e7f5d&quot;&gt;강의 슬라이드&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 05 Apr 2017 21:52:28 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/05/jwp-01/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/05/jwp-01/</guid>
        
        <category>study jwp</category>
        
        
      </item>

      <item>
        <title>emacs 사용 시작!</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#why-emacs&quot; id=&quot;markdown-toc-why-emacs&quot;&gt;Why Emacs?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#emacs-download&quot; id=&quot;markdown-toc-emacs-download&quot;&gt;Emacs download&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#evil&quot; id=&quot;markdown-toc-evil&quot;&gt;EVIL&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#evil-설치&quot; id=&quot;markdown-toc-evil-설치&quot;&gt;EVIL 설치&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#emacs-종료&quot; id=&quot;markdown-toc-emacs-종료&quot;&gt;Emacs 종료&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;why-emacs&quot;&gt;Why Emacs?&lt;/h1&gt;

&lt;p&gt;나는 코드는 물론이고 모든 글을 Vim에서 작성한다. 세상에 Vim만큼 편리하고 쾌적한 텍스트 편집 도구는 존재하지 않는다고 생각한다. Vim에 대한 애정이 있다. 하지만 평생 Vim만 쓸 것인가? Emacs도 궁금하다. 기왕이면 둘 다 써보고 장점들만 취합해보고 싶다. 그냥 시작하면 진입장벽이 높을 테니 예전부터 눈독들인 Evil 모드로 시작해보고자 한다.&lt;/p&gt;

&lt;h1 id=&quot;emacs-download&quot;&gt;Emacs download&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://emacsformacosx.com/&quot;&gt;Emacs For Mac OS X&lt;/a&gt;에서 GUI 버전을 받을 수 있다.&lt;/li&gt;
  &lt;li&gt;터미널에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew install emacs&lt;/code&gt;로 쉽게 설치할 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;evil&quot;&gt;&lt;a href=&quot;https://github.com/emacs-evil/evil&quot;&gt;EVIL&lt;/a&gt;&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;EVIL은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt;xtensible &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vi&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;l&lt;/code&gt;ayer for Emacs의 줄임말인 모양이다.&lt;/li&gt;
  &lt;li&gt;EVIL은 Emacs위에 Vi를 올리는 것이므로 &lt;a href=&quot;https://en.wikipedia.org/wiki/Editor_war&quot;&gt;편집기 전쟁&lt;/a&gt;의 관점에서 보면 신성모독이라고도 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;evil-설치&quot;&gt;EVIL 설치&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/emacs-evil/evil#install&quot;&gt;Evil의 Install&lt;/a&gt;을 참고하여 다음과 같이 작업해 주었다.&lt;/p&gt;

&lt;p&gt;다운로드 한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git clone git@github.com:emacs-evil/evil.git
$ cd ~/.emacs.d/
$ ln -s ~/git/evil/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.emacs&lt;/code&gt;파일에 다음 코드를 추가한다.&lt;/p&gt;

&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-to-list&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;load-path&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;~/.emacs.d/evil&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;evil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;evil-mode&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 하고 Emacs를 실행하니 hjkl 키로 커서를 움직일 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;emacs-종료&quot;&gt;Emacs 종료&lt;/h2&gt;

&lt;p&gt;종료는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;c-x&amp;gt;&amp;lt;c-c&amp;gt;&lt;/code&gt;로 할 수 있다.&lt;/p&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://emacsformacosx.com/&quot;&gt;Emacs For Mac OS X&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/emacs-evil/evil#install&quot;&gt;Evil Install&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/emacs-evil/evil/master/doc/evil.pdf&quot;&gt;Evil PDF manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Editor_war&quot;&gt;Editor war&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 03 Apr 2017 16:33:24 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/03/emacs-start/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/03/emacs-start/</guid>
        
        <category>emacs evil</category>
        
        
      </item>

      <item>
        <title>Next JWP Study 00</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#nextstep-jwp&quot; id=&quot;markdown-toc-nextstep-jwp&quot;&gt;NextStep JWP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#수업-전-준비사항&quot; id=&quot;markdown-toc-수업-전-준비사항&quot;&gt;수업 전 준비사항&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#aws-인스턴스-생성-및-ssh를-통한-접속&quot; id=&quot;markdown-toc-aws-인스턴스-생성-및-ssh를-통한-접속&quot;&gt;AWS 인스턴스 생성 및 ssh를 통한 접속&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#주의-사항&quot; id=&quot;markdown-toc-주의-사항&quot;&gt;주의 사항&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;nextstep-jwp&quot;&gt;NextStep JWP&lt;/h1&gt;

&lt;p&gt;4월 3일, 즉 다음주 월요일부터 회사에서 &lt;a href=&quot;http://www.javajigi.net/&quot;&gt;자바지기&lt;/a&gt; 박재성 님의 &lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr&quot;&gt;NextStep JWP&lt;/a&gt;수업을 듣게 되었다.&lt;/p&gt;

&lt;p&gt;내가 수강 지원을 한 이유는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;박재성님의 NextStep 수업은 명강의로 유명하고, 이번 기회에 회사 돈으로 교육을 받을 수 있다.&lt;/li&gt;
  &lt;li&gt;Java로는 주로 유지보수 작업만 해왔기 때문에 밑바닥부터 시작하는 통합된 학습의 필요성을 느끼고 있었다.&lt;/li&gt;
  &lt;li&gt;마침 요즘 하는 일이 PHP 레거시를 Java로 이행하는 작업과 관련이 있다.&lt;/li&gt;
  &lt;li&gt;부가적으로 AWS와 Spring을 배워보고 싶다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;수업-전-준비사항&quot;&gt;수업 전 준비사항&lt;/h1&gt;

&lt;p&gt;수업 전 자신의 컴퓨터 환경을 다음과 같이 준비해야 한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JDK 8.0&lt;/li&gt;
  &lt;li&gt;STS 또는 IntelliJ IDEA&lt;/li&gt;
  &lt;li&gt;Git 설치&lt;/li&gt;
  &lt;li&gt;Github 계정 생성&lt;/li&gt;
  &lt;li&gt;크롬 설치&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nextstep.camp/courses/-KgDNT4rfavb_BzYLBXr&quot;&gt;수강신청&lt;/a&gt;하기&lt;/li&gt;
  &lt;li&gt;AWS 인스턴스 생성 및 ssh를 통한 접속(2주차까지 진행해도 괜찮음)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;모두 평소에 잘 쓰고 있는 것들을 쓰면 될듯. AWS 인스턴스 생성만 해두면 되겠다.&lt;/p&gt;

&lt;h2 id=&quot;aws-인스턴스-생성-및-ssh를-통한-접속&quot;&gt;AWS 인스턴스 생성 및 ssh를 통한 접속&lt;/h2&gt;

&lt;p&gt;아마존 아이디 있으니까 새로 생성할 필요는 없다.&lt;/p&gt;

&lt;p&gt;박재성 님의 &lt;a href=&quot;https://www.youtube.com/watch?v=RvWC4njEKUY&amp;amp;feature=youtu.be&quot;&gt;AWS 인스턴스 생성 및 SSH를 통한 로그인&lt;/a&gt;을 참고하여 아래와 같이 작업하였다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AWS에 로그인하여 EC2 선택.&lt;/li&gt;
  &lt;li&gt;Launch Instance를 클릭하여 새로운 인스턴스를 만든다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ap-northeast-2.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-2#LaunchInstanceWizard:&quot;&gt;서버 선택 화면&lt;/a&gt; : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ubuntu Server 16.04 LTS (HVM), SSD Volume Type&lt;/code&gt; 선택.
    &lt;ul&gt;
      &lt;li&gt;이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Free tier eligible&lt;/code&gt; 딱지가 붙어 있는 설정을 선택한다.&lt;/li&gt;
      &lt;li&gt;Next 버튼 클릭.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Step 3: Default 설정, Next 클릭.&lt;/li&gt;
  &lt;li&gt;Step 4: Default 설정, Next 클릭.&lt;/li&gt;
  &lt;li&gt;Step 5: Default 설정, Next 클릭.&lt;/li&gt;
  &lt;li&gt;Step 6: Configure Security Group
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security group name&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my security group&lt;/code&gt;으로 수정.&lt;/li&gt;
      &lt;li&gt;Add Rule: HTTP - TCP - 80 포트 추가.&lt;/li&gt;
      &lt;li&gt;Add Rule: Custom TCP Rule - TCP - 8080 포트 추가.&lt;/li&gt;
      &lt;li&gt;Review and Launch 클릭.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;지금까지 설정한 내용을 한 번에 볼 수 있다.
    &lt;ul&gt;
      &lt;li&gt;Launch 클릭.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Key pair는 적당히 알아서 갖고 있는 것을 쓰거나 새로 만들거나 한다.&lt;/li&gt;
  &lt;li&gt;Launch Instances 클릭.&lt;/li&gt;
  &lt;li&gt;View Instances 버튼으로 인스턴스들의 현재 상태를 볼 수 있다.
    &lt;ul&gt;
      &lt;li&gt;방금 생성한 서버를 선택한 다음, 아래쪽을 보면 DNS와 IP가 있다. 일단 IP를 복사한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;터미널을 열고 다음과 같이 입력한다.
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ssh -i {pem 파일} ubuntu@{ip주소}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그랬더니 다음과 같은 에러가 발생한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for &apos;/Users/xxx/xxx/foo.pem&apos; are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key &quot;/Users/xxx/xxx/foo.pem&quot;: bad permissions
Permission denied (publickey).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;too open permission 문제이니 다음과 같이 400으로 변경해주면 된다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ chmod 400 foo.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;접속에 성공하면 일단 다음과 같이 한글 설정부터 해주자.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo locale-gen ko_KR.UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이러면 학습할 준비는 완료된 것이다.&lt;/p&gt;

&lt;h2 id=&quot;주의-사항&quot;&gt;주의 사항&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;혹시 요금 폭탄이 터질 수 있으니 사용하지 않는 인스턴스는 stop 하도록 한다.&lt;/li&gt;
  &lt;li&gt;인스턴스는 start 할 때마다 DNS와 IP가 바뀌므로 다음에 다시 시작할 때에는 새로운 IP를 사용해 접속해야 한다.&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 02 Apr 2017 12:15:32 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/04/02/jwp-00-prepare/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/04/02/jwp-00-prepare/</guid>
        
        <category>study jwp aws</category>
        
        
      </item>

      <item>
        <title>텔레그램 봇 스켈레톤 만들기</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#준비물&quot; id=&quot;markdown-toc-준비물&quot;&gt;준비물&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#텔레그램-api-token-얻기&quot; id=&quot;markdown-toc-텔레그램-api-token-얻기&quot;&gt;텔레그램 API TOKEN 얻기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#코딩&quot; id=&quot;markdown-toc-코딩&quot;&gt;코딩&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#webjs는-왜-있는-거죠&quot; id=&quot;markdown-toc-webjs는-왜-있는-거죠&quot;&gt;web.js는 왜 있는 거죠?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#config-variable-설정&quot; id=&quot;markdown-toc-config-variable-설정&quot;&gt;Config Variable 설정&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#배포&quot; id=&quot;markdown-toc-배포&quot;&gt;배포&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#테스트&quot; id=&quot;markdown-toc-테스트&quot;&gt;테스트&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sleep-방지-처리&quot; id=&quot;markdown-toc-sleep-방지-처리&quot;&gt;sleep 방지 처리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#links&quot; id=&quot;markdown-toc-links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;심심해서 텔레그램 봇을 만들어 보았다.&lt;br /&gt;
봇을 만든 과정을 요약해 남겨본다.&lt;/p&gt;

&lt;h2 id=&quot;준비물&quot;&gt;준비물&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;텔레그램 API TOKEN&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://heroku.com/&quot;&gt;Heroku&lt;/a&gt; 계정
    &lt;ul&gt;
      &lt;li&gt;무료로 봇을 돌리기 위해 Heroku를 선택했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://uptimerobot.com/&quot;&gt;uptimerobot.com&lt;/a&gt; 계정
    &lt;ul&gt;
      &lt;li&gt;Heroku 앱의 sleep 을 방지하기 위한 꼼수.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;텔레그램-api-token-얻기&quot;&gt;텔레그램 API TOKEN 얻기&lt;/h2&gt;
&lt;p&gt;텔레그램에서 &lt;a href=&quot;https://telegram.me/botfather&quot;&gt;@BotFather&lt;/a&gt;를 찾아 다음 순서대로 말을 걸면 된다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/start&lt;/code&gt; : @BotFather를 활성화한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/newbot&lt;/code&gt; : 새로운 봇을 만들어달라고 요청한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이후로는 @BotFather가 봇의 이름을 물어보니 적당한 이름을 요청하면 된다.
그러면 @BotFather가 답변으로 API TOKEN을 보내준다.&lt;/p&gt;

&lt;p&gt;자세한 내용은 &lt;a href=&quot;https://core.telegram.org/bots&quot;&gt;공식 문서&lt;/a&gt; 참고.&lt;/p&gt;

&lt;h2 id=&quot;코딩&quot;&gt;코딩&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;package.json&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;telegram-bot&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;index.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;echo &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Error: no test specified&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; exit 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node index.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dev_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;export $(cat .config) &amp;amp;&amp;amp; node index.js&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;repository&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;git&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;git+https://github.com/johngrib/telegram-bot.git&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;John Grib&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;license&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MIT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;bugs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/johngrib/telegram-bot/issues&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;homepage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/johngrib/telegram-bot#readme&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;express&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^4.15.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;get-json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.0.3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;node-telegram-bot-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^0.27.0&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;index.js&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./bot&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./web&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;bot.js&lt;/em&gt; : bot의 비즈니스 로직이 들어갈 곳이다.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TelegramBot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;node-telegram-bot-api&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getToken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TELEGRAM_TOKEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TelegramBot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;polling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\/&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;echo &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;.+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;chatId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;chat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sendMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;chatId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;web.js&lt;/em&gt; : http end-point를 만들어 준다.&lt;/p&gt;
&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;packageInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./package.json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;packageInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Web server started at http://%s:%s&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;webjs는-왜-있는-거죠&quot;&gt;web.js는 왜 있는 거죠?&lt;/h2&gt;

&lt;p&gt;사실 bot.js만 있어도 봇은 돌아간다. 즉 web.js는 일종의 군더더기 코드라 할 수 있다.&lt;br /&gt;
이게 필요한 이유는 이 코드를 Heroku에서 구동하기로 결정했기 때문이다.&lt;/p&gt;

&lt;p&gt;Heroku는 일정 시간 동안 deploy한 앱에 접속 요청이 없을 경우, 앱을 sleep 시켜버린다.
물론 sleep 이 된다고 해서 영원한 잠에 빠지거나 하는 건 아니고, 다음 요청이 있을 때까지 죽여 놓는 것이다.
새로운 요청을 받으면 앱을 새로 구동한 다음 웹 페이지를 보여준다.
평범한 블로그나 웹 사이트라면 sleep 상태라고 해도 10~30초 정도만 기다리면 되는 것이다.&lt;/p&gt;

&lt;p&gt;하지만 실험을 해보니 봇은 웹이 아니어서 그런지 한 번 sleep 상태로 빠져들면 다시는 깨어나지 않았다.&lt;/p&gt;

&lt;p&gt;그래서 나온 꼼수가 http end point를 만든 다음, 주기적으로 ping을 보내주는 서비스에 봇의 http end point를 등록해서 봇이 잠들지 않도록 해주는 것이다. 이런 서비스들 중 하나가 바로 &lt;a href=&quot;https://uptimerobot.com/&quot;&gt;uptimerobot.com&lt;/a&gt;. 무료로 가입할 수 있고, 사용법도 단순하다.&lt;/p&gt;

&lt;p&gt;위의 코드를 Heroku에 배포한 다음, uptimerobot에 uri를 등록해 두면 봇 스켈레톤이 완성되는 셈이다.&lt;/p&gt;

&lt;h2 id=&quot;config-variable-설정&quot;&gt;Config Variable 설정&lt;/h2&gt;

&lt;p&gt;배포하기 전에 Heroku Dashboard 에서 Config Variable에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TELEGRAM_TOKEN&lt;/code&gt;을 등록해 준다.&lt;br /&gt;
이렇게 등록한 값은 node.js 코드에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;process.env.TELEGRAM_TOKEN&lt;/code&gt; 으로 접근할 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;배포&quot;&gt;배포&lt;/h2&gt;

&lt;p&gt;Heroku는 배포가 쉬워서 좋다.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push heroku master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;테스트&quot;&gt;테스트&lt;/h2&gt;

&lt;p&gt;봇이 잘 돌아가는지 텔레그램으로 확인해 본다. 위의 코드대로라면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/echo test&lt;/code&gt; 등으로 확인 가능하다.&lt;/p&gt;

&lt;h2 id=&quot;sleep-방지-처리&quot;&gt;sleep 방지 처리&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://uptimerobot.com/&quot;&gt;uptimerobot.com&lt;/a&gt;에 봇의 도메인 주소를 등록해 준다.&lt;/p&gt;

&lt;h2 id=&quot;links&quot;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/johngrib/telegram-bot&quot;&gt;https://github.com/johngrib/telegram-bot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://mvalipour.github.io/node.js/2015/11/10/build-telegram-bot-nodejs-heroku&quot;&gt;https://mvalipour.github.io/node.js/2015/11/10/build-telegram-bot-nodejs-heroku&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 12 Mar 2017 21:08:16 +0900</pubDate>
        <link>https://porcochips.github.io/blog/2017/03/12/telegram-bot/</link>
        <guid isPermaLink="true">https://porcochips.github.io/blog/2017/03/12/telegram-bot/</guid>
        
        <category>node-js telegram heroku chatbot bot</category>
        
        
      </item>

  </channel>
</rss>
