<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>jasonbla</title>
    <link>https://jasonbla.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 24 Aug 2026 10:55:40 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jason hwang</managingEditor>
    <image>
      <title>jasonbla</title>
      <url>https://t1.daumcdn.net/cfile/tistory/2150D635578AF0A105</url>
      <link>https://jasonbla.tistory.com</link>
    </image>
    <item>
      <title>[Android] 피카소(Picasso) 라이브러리 소개 및 주의할 점</title>
      <link>https://jasonbla.tistory.com/15</link>
      <description>&lt;h4&gt;피카소(Picasso) 라이브러란?&lt;/h4&gt;&lt;p&gt;피카소(Picasso)는 외부로부터 이미지를 불러와야 할 경우 유용하게 사용할 수 있는 라이브러리입니다.&lt;/p&gt;
&lt;p&gt;매우 간단한 코드 몇 줄로 이미지 로딩, 메모리 &amp;amp; 디스크 캐싱, 변형(Transforming)을 가능케 합니다.&lt;/p&gt;&lt;h4&gt;피카소 라이브러리의 장점&lt;/h4&gt;&lt;p&gt;피카소 공식 사이트에서 강조(?)하고 있는 장점은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;- Handling ImageView recycling and download cancelation in an adapter.&lt;/p&gt;
&lt;p&gt;- Complex image transformations with minimal memory use.&lt;/p&gt;
&lt;p&gt;- Automatic memory and disk caching.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;이미지를 화면에 보여주는 일에 수반되는 부가적인 작업이 정말 많음을 짐작할 수 있습니다.&amp;nbsp;(캐싱, 이미지 가공, 메모리 관리 등)&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;피카소(Picasso)&lt;/span&gt;&lt;/b&gt;와 비슷한 &lt;b&gt;&lt;span style=&quot;color: rgb(0, 85, 255);&quot;&gt;글라이드(Glide)&lt;/span&gt;&lt;/b&gt;라는 라이브러리도 있으며, 사용법 또한 거의 같습니다.&lt;/p&gt;
&lt;p&gt;다음 아티클에 어떤 차이점이 있는지 상세하게 설명되어 있으니 사용하고자 하는 시스템에 맞게 사용하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;https://medium.com/@multidots/glide-vs-picasso-930eed42b81d&lt;/p&gt;&lt;/blockquote&gt;&lt;h4&gt;공식 사이트&lt;/h4&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;Picasso Library : https://github.com/square/picasso&lt;/p&gt;
&lt;p&gt;Glide Library : https://github.com/bumptech/glide&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;둘 다 워낙 유명한 라이브러리이고, 구글링을 통해 거의 모든 정보를 얻을 수 있기 때문에 여기서는 상세한 라이브러리 사용법을 소개하지 않고, 개발하면서 겪었던 메모리 문제에 대해 글을 써보려 합니다.&lt;/p&gt;&lt;h4&gt;피카소 라이브러리 사용법&lt;/h4&gt;&lt;p&gt;다음과 같이 매우 간단하게 imageView에 이미지를 할당할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;pre class=&quot;brush: java&quot;&gt;Picasso
    .with(context)
    .load(&quot;http://i.imgur.com/DvpvklR.png&quot;)
    .into(imageView);
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;하지만, ImageView에 대한 어떠한 정보도 현재로서 알 수 없기 때문에, 피카소는 원본 이미지를 그대로 디스크에 저장하고 메모리에 할당합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그리고 imageView가 inflate될때마다 실시간으로 메모리에서 가져와 imageView에 맞게 처리하게 되는데, 이 경우에&amp;nbsp;예를 들어 imageView가 200x200 밖에 되지 않더라도 Picasso는 원본 이미지를 계속해서 메모리에 유지하고, 실시간으로 처리하려고 시도합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그래서 다음과 같이 resize 처리를 해주거나, fit 함수를 사용해주면 이러한 문제를 해결할 수 있습니다.&amp;nbsp;사실 fit 함수는 imageView의 크기를 계산해서 내부적으로 resize를 해주기 때문에 거의 같은 성능을 보이구요.&amp;nbsp;물론 imageView의 크기가 고정적이라면, 명시적인 width &amp;amp; height를 주는 게 가장 좋은 방법입니다 : )&lt;/p&gt;&lt;h4&gt;참고할 아티클&lt;/h4&gt;&lt;p&gt;더 상세한 내용은 다음 아티클에 정말 잘 소개되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;캐시 정책 : https://futurestud.io/tutorials/picasso-influencing-image-caching&lt;/p&gt;
&lt;p&gt;리사이징 &amp;amp; 스케일링 : https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit&lt;/p&gt;&lt;/blockquote&gt;&lt;h4&gt;문제 1 : Fit 또는 Resize를 사용하지 못하는 경우&lt;/h4&gt;&lt;p&gt;피카소는 해야 할 일을 모두 마친 후 (캐시, 가공 등) into 메서드를 통해 imageView에 이미지를 할당합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그러면 Bitmap을 사용해야 하는 경우는? 다음과 같이 Target Callback을 활용해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;Target target = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        doSomething(bitmap)
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
};

Picasso
        .with(this)
        .load(&quot;http://i.imgur.com/DvpvklR.png&quot;)
        .into(target);
&lt;/pre&gt;
&lt;p&gt;그런데, Target Callback을 통해 bitmap을 전달받는 경우는 resize, centerCrop, fit 등 몇몇 함수를 사용할 수 없습니다. 만약 함께 사용하려 시도한다면 다음 에러가 발생합니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Caused by: java.lang.IllegalStateException: Fit cannot be used with a Target.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;개발할 때, Bitmap을 사용해야 하는 경우는 다음과 같았는데&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;- Notification의 thumbnail&lt;/p&gt;
&lt;p&gt;- 락 스크린의 미디어 thumbnail&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;피카소 라이브러리의 Fit 함수 구현체를 보면 다음과 같이 기술되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;/**
 * Attempt to resize the image to fit exactly into the target {@link ImageView}'s bounds. This
 * will result in delayed execution of the request until the {@link ImageView} has been laid out.
 * &lt;em&gt;Note:&lt;/em&gt; This method works only when your target is an {@link ImageView}.
 */
public RequestCreator fit() {
  deferred = true;
  return this;
}
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;왜 Fit 함수와 Target이 Bitmap인 경우 함께 사용할 수 없는지 정확한 이유를 알기는 어렵지만… 어쨌든&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Resize, centerCrop 등의 함수를 사용할 수 없으니, 정사각형 1:1 비율이 아닌 이미지의 경우는 어쩔 수 없이 아래처럼 Bitmap을 후가공하는 커스텀 함수를 구현하여 아래와 같이 처리하였습니다.&lt;/p&gt;
&lt;pre class=&quot;“brush:java”&quot;&gt;Transformation transformation = new Transformation() {
    @Override
    public Bitmap transform(Bitmap source) {
        return myCenterCrop(source);
    }
 
    @Override
    public String key() {
        return null;
    }
}
 
Picasso
        .with(this)
        .load(url)
        .transform(transformation)
        .into(target);
 
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h4&gt;문제 2 : 메모리 증가 문제&lt;/h4&gt;&lt;p&gt;onBitmapLoaded 콜백을 통해 bitmap을 centerCrop한 후 필요한 곳에 적용하니 잘 작동되는것 처럼 보였습니다.&lt;/p&gt;
&lt;p&gt;고해상도 이미지로 테스트해보기 전까지는…..&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;테스트를 하다 보니, 2M 이상의 고해상도 이미지를 불러올 때마다 메모리가 20mb 가까이 치솟는 현상을 발견하였습니다….!&lt;/p&gt;
&lt;p&gt;5번만 호출해도 100mb는 훌쩍 넘어버리고 결국 앱이 죽는 현상까지 발생했습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;onBitmapLoaded를 통해 넘어온 bitmap을 가공해서 사용할 경우, 가공된 bitmap을 캐시할 수 없기 때문에 계속해서 메모리 누수가 발생하는 것입니다. (가공된 bitmap을 캐시하도록 따로 추가한다면 모르지만)&lt;/p&gt;&lt;h4&gt;해결방법&lt;/h4&gt;&lt;p&gt;이를 해결하기 위해서는 다음과 같이 onBitmapLoaded로 넘어오기 이전에 이미지 처리를 해야 가공된 이미지를 메모리에 올릴 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;Transformation transformation = new Transformation() {
    @Override
    public Bitmap transform(Bitmap source) {
        return myCenterCrop(source);
    }

    @Override
    public String key() {
        return null;
    }
}

Picasso
        .with(this)
        .load(url)
        .transform(transformation)
        .into(target);

&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;이후, transform 함수 내에서 로그를 찍어보면 최초 한 번만 호출되는 것을 확인할 수 있고, 더불어 메모리 누수도 막을 수 있습니다.&lt;/p&gt;&lt;h4&gt;정리&lt;/h4&gt;&lt;p&gt;피카소라는 막강한 라이브러리를 사용하면 빠르게 결과물을 만들어 낼 수 있지만, 라이브러리의 특성 및 원리를 제대로 이해하지 않고 사용했다가 큰코다칠 수 있다는 경험을 깨닫게 된 소중한 경험이었네요.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;결론 : 잘 알고 쓰자.&amp;nbsp;&lt;img src=&quot;//i1.daumcdn.net/deco/contents/emoticon/things_20.gif?v=2&quot; border=&quot;0&quot; class=&quot;txc-emo&quot;&gt;&lt;/p&gt;</description>
      <category>Programming</category>
      <category>Android</category>
      <category>glide</category>
      <category>memory leak</category>
      <category>Picasso</category>
      <category>메모리누수</category>
      <category>메모리릭</category>
      <category>안드로이드</category>
      <category>피카소</category>
      <category>피카소라이브러리</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/15</guid>
      <comments>https://jasonbla.tistory.com/15#entry15comment</comments>
      <pubDate>Sat, 23 Sep 2017 14:30:05 +0900</pubDate>
    </item>
    <item>
      <title>[iOS] Safari에서 Pinch Zoom 막기(How to Disable the Pinch-to-Zoom)</title>
      <link>https://jasonbla.tistory.com/13</link>
      <description>&lt;h4&gt;참고 링크&lt;/h4&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/4389932/how-do-you-disable-viewport-zooming-on-mobile-safari&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;how-do-you-disable-viewport-zooming-on-mobile-safari&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.daddydesign.com/wordpress/how-to-disable-the-pinch-to-zoom-functionality-on-your-responsive-website/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;how-to-disable-the-pinch-to-zoom-functionality-on-your-responsive-website/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/37808180/disable-viewport-zooming-ios-10-safari&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;disable-viewport-zooming-ios-10-safari&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Responsive Web이 등장하면서 더이상 모바일 환경에서 Zoom In/Out을 해야 할 필요를 못느끼게 되었고, 이에 따라 대부분의 사이트에서 meta tag를 활용하여 페이지에 대한 Zoom을 Disable 시키게 되었다.&amp;nbsp;&lt;/p&gt;&lt;h4&gt;How to Disable the Pinch to Zoom?&lt;/h4&gt;&lt;p&gt;다음 코드를 추가하면 간단하게&amp;nbsp;Zoom In/Out을 막을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt; 
&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot;&amp;gt;
&lt;/pre&gt;&lt;h4&gt;그런데...?&lt;/h4&gt;&lt;p&gt;iOS 10의 새 기능으로 다음과 같이 추가되었다고 한다.&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;ul style=&quot;margin: 0px 0px 0px 30px; padding: 0px; border: 0px; font-size: 15px; color: rgb(36, 39, 41); font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif;&quot;&gt;&lt;li style=&quot;margin: 0px; padding: 0px; border: 0px; word-wrap: break-word;&quot;&gt;To improve accessibility on websites in Safari, users can now pinch-to-zoom even when a website sets&amp;nbsp;&lt;code style=&quot;margin: 0px; padding: 1px 5px; border: 0px; font-size: 13px; font-family: Consolas, Menlo, Monaco, &amp;quot;Lucida Console&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;DejaVu Sans Mono&amp;quot;, &amp;quot;Bitstream Vera Sans Mono&amp;quot;, &amp;quot;Courier New&amp;quot;, monospace, sans-serif; background-color: rgb(239, 240, 241); white-space: pre-wrap;&quot;&gt;user-scalable=no&lt;/code&gt;&amp;nbsp;in the viewport.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;그렇다... user-scalable=no 임에도 불구하고 pinch zoom을 허용하라는 이야기이다. 역시나 최신 버전의 iOS에서는 zoom이 disable되어 있음에도 불구하고 Zoom In/Out이 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;이러한 정책이 어떻게 결정되었는지는 알 수 없지만, 개발자는 언제나 차선책을 강구해야만 하는.... 그런 존재가 아닐까. (&lt;strike&gt;애플이 그렇다면..&lt;/strike&gt;) 아무튼 &lt;a href=&quot;http://stackoverflow.com/questions/37808180/disable-viewport-zooming-ios-10-safari&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;stackoverflow의 답변&lt;/a&gt;에서 발췌한 javascript 코드를 통해 zoom을 disable하는 방법은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1) Pinch Zoom 끄기&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:javascript&quot;&gt; 
document.documentElement.addEventListener('touchstart', function (event) {
    if (event.touches.length &amp;gt; 1) {
      event.preventDefault();
    }
}, false);
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2) Double tab Zoom 끄기&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt; 
var lastTouchEnd = 0;
document.documentElement.addEventListener('touchend', function (event) {
    var now = (new Date()).getTime();
    if (now - lastTouchEnd &amp;lt;= 300) {
      event.preventDefault();
    }
    lastTouchEnd = now;
}, false);
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1)의 경우 touchstart의 event를 받아 touch의 개수를 체크한 뒤, 1개 이상이면(pinch zoom일 경우) 이벤트를 무시하는 방법을 사용하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2)의 경우 touchend 시점의 시간을 확인하여 300ms 이하면 이벤트를 무시하는 방법을 사용하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;테스트 확인 결과, 두 방법 모두 잘 작동하며 사이트의 UX에 맞게 적절히 사용하는 것이 바람직하다고 생각된다.&lt;/p&gt;</description>
      <category>Programming/Javascript</category>
      <category>metatag</category>
      <category>pinch-to-zoom</category>
      <category>Safari</category>
      <category>줌</category>
      <category>줌막기</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/13</guid>
      <comments>https://jasonbla.tistory.com/13#entry13comment</comments>
      <pubDate>Thu, 20 Apr 2017 01:23:41 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Failed to instantiate Pageable bean 해결</title>
      <link>https://jasonbla.tistory.com/12</link>
      <description>&lt;h4&gt;Spring에서 Pageable이란?&lt;/h4&gt;&lt;p&gt;반복되는 리스트를 출력해야 하는 경우 Pagination 처리는 없어서는 안될 요소이다. Spring에서는 이러한 Pagination을 쉽게 처리할 수 있도록 Query Parameter를 자동으로 매핑해 객체로 생성해주는 Pageable Interface를 제공한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;참고&lt;/h4&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html&lt;/p&gt;&lt;p&gt;http://forum.spring.io/forum/spring-projects/data/114494-how-to-manage-web-pagination-with-the-guide-of-spring-data-web-pagination&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;사용법 및 예시&lt;/h4&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;아래와 같이 Pageable Parameter를 적용할 메서드에 추가해준다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/267AB14B5882E3B201&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F267AB14B5882E3B201&quot; width=&quot;820&quot; height=&quot;63&quot; filename=&quot;Screen Shot 2017-01-21 at 1.28.34 PM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그리고 다음과 같은 Parameter를 url에 설정하여 사용할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ex) /api/items?page=0&amp;amp;size=10&amp;amp;sort=asc&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/22239D415882E5621B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F22239D415882E5621B&quot; width=&quot;820&quot; height=&quot;185&quot; filename=&quot;Screen Shot 2017-01-21 at 1.35.58 PM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참고 :&amp;nbsp;http://docs.spring.io/spring-data/data-commons/docs/current/reference/html/#core.web&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Failed to instantiate Pageable bean 에러날 경우&lt;/h4&gt;&lt;div&gt;Pageable은 Interface이기 때문에 아래와 같이 annotation-driven 속성에 PageableHandlerMethodArgumentResolver Class를 지정해주어야 에러가 발생하지 않는다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div&gt;&amp;lt;bean class=&quot;org.springframework.data.web.PageableHandlerMethodArgumentResolver&quot; /&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21776C485882E41A0B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21776C485882E41A0B&quot; width=&quot;820&quot; height=&quot;114&quot; filename=&quot;Screen Shot 2017-01-21 at 1.30.53 PM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Framework/Spring</category>
      <category>pageable</category>
      <category>pagination</category>
      <category>spring</category>
      <category>스프링</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/12</guid>
      <comments>https://jasonbla.tistory.com/12#entry12comment</comments>
      <pubDate>Sat, 21 Jan 2017 13:40:23 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Asset Studio 활용하여 해상도별 Launcher Icon 세팅하기</title>
      <link>https://jasonbla.tistory.com/11</link>
      <description>&lt;h4&gt;참고자료&lt;/h4&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;https://developer.android.com/studio/write/image-asset-studio.html#access&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이클립스 기반에서 안드로이드 스튜디오로 넘어가면서 성능은 물론이고 개발자를 위한(?) 기능들이 정말 잘 갖추어졌다. 그 중 하나가 Asset Studio인데 안드로이드 App 개발에 필수적인 해상도별 이미지 세팅을 자동으로 지원해준다. 구글 플레이 콘솔에서 APK 탭에 들어가면 지원/미지원 기기의 숫자를 볼 수 있는데 안드로이드 진영의 파편화된 디바이스의 숫자는 정말 가늠하기 힘들 정도이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;820&quot; width=&quot;820&quot; exif=&quot;{}&quot; id=&quot;tx_entry_94419_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/242D253F587250641B&quot; height=&quot;121&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제&amp;nbsp;Android Studio의 Asset Studio를 이용하면 해상도별 아이콘을 쉽게 생성 및 적용할 수 있다. 이런 기능이 없었던 시절에는 해상도별로 이미지를 크롭해주는 사이트를 활용하곤 했었는데 이제는 그럴 필요가 없을듯 하다 : )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Project &amp;gt; res &amp;gt; New &amp;gt; Image Asset&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;820&quot; width=&quot;820&quot; exif=&quot;{}&quot; id=&quot;tx_entry_94683_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/220A9133587251B710&quot; height=&quot;705&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Launcher Icon의 경우 Asset Type에 Image를 선택하면 로컬에 있는 이미지 파일을 불러와서 적용할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;img actualwidth=&quot;820&quot; width=&quot;820&quot; exif=&quot;{}&quot; id=&quot;tx_entry_28458_&quot; class=&quot;txc-image&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/236E9134587251FE17&quot; height=&quot;679&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Programming</category>
      <category>android stduio</category>
      <category>asset studio</category>
      <category>안드로이드 해상도</category>
      <category>안드로이드스튜디오</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/11</guid>
      <comments>https://jasonbla.tistory.com/11#entry11comment</comments>
      <pubDate>Sun, 8 Jan 2017 23:56:13 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Play Store 업데이트, zipalign 사용법</title>
      <link>https://jasonbla.tistory.com/10</link>
      <description>&lt;p&gt;+ 내용 추가 (2017.1.8)&lt;/p&gt;
&lt;p&gt;최신 버전의 Android Studio에서는 KeyStore 세팅만 잘 되어 있으면 Zipalign을 사용할 필요 없이 Build &amp;gt; Generate Signed APK 메뉴를 통해 Release APK를 바로 뽑아낼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Play Store에 배포하는 절차 중 정리해 두어야 할 포인트를 기록하고자 포스팅. 기본적으로 Play Store에 어떻게 배포하는지&amp;nbsp;아래에 잘 설명되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://support.google.com/googleplay/android-developer/answer/113469?hl=ko&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://support.google.com/googleplay/android-developer/answer/113469?hl=ko&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;대부분 읽어보면 쉽게 채울 수 있는 항목이고 시간이 오래 걸리지 않는다. (스크린샷, 배포 국가 설정, 저작권, 언어, App 설명 등) 다만 업로드 할 APK는 정식으로 서명 되어 있어야만 스토어에 배포할 수 있다. 자세한 설명은 아래 링크와 함께 참고..&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;margin-right: 0px; margin-bottom: 16px; margin-left: 0px; font-size: 16px; color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif;&quot;&gt;Android requires that all APKs be digitally signed with a certificate before they can be installed. This document describes how to sign your APKs using Android Studio, including creating and storing your certificate, signing different build configurations using different certificates, and configuring the build process to sign your APKs automatically.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.android.com/studio/publish/app-signing.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/studio/publish/app-signing.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;최초로 APK를 서명할 때는 다음 링크부터 참고하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;Sign your release build&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.android.com/studio/publish/app-signing.html#release-mode&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.android.com/studio/publish/app-signing.html#release-mode&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;만약 Key Store를 최초로&amp;nbsp;등록할 경우 비밀번호를 설정해야 하는데 이를 잊어버리게 되면 APK 배포 이후 새버전 업데이트를 할 때 문제가 되므로 잘 관리해야 한다. (잃어버리면 되찾을 수 없음)&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;정리하자면&lt;/h4&gt;&lt;p&gt;다음과 같고, (1)은 최초 signing시에만 생성하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1. KeyStore 생성&lt;/p&gt;
&lt;p&gt;2. KeyStore를 사용해 Signed APK 만들기&lt;/p&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;2.1. unaligned -&amp;gt; aligned APK로 변환&lt;/p&gt;
&lt;p&gt;3. &lt;a href=&quot;https://play.google.com/apps/publish/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Developer Console&lt;/a&gt;로 이동 후 APK&amp;nbsp;업로드 및 배포&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;zipalign사용하여 align APK 만들기&lt;/h4&gt;&lt;pre class=&quot;no-pretty-print&quot; style=&quot;margin-top: 6px; margin-bottom: 6px; color: rgb(0, 102, 0); font-stretch: normal; line-height: 18px; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Monaco, Courier, monospace; -webkit-font-smoothing: subpixel-antialiased; padding: 1em; overflow: auto; border: 1px solid rgb(221, 221, 221); background: rgb(247, 247, 247);&quot;&gt;zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;APK 버전 관리 Tip&lt;/h4&gt;&lt;p&gt;스토어에 배포할 때 반드시 versionCode를 업데이트 해주어야 하는데, build.gradle에 다음과 같이 설정하면 버전이 포함된 이름으로 APK를 생성해 주기 때문에 꽤나 관리하기에 편리하다. &lt;strike&gt;(versionCode, versionName은 직접 카운팅 해주어야 하는 것은 함정)&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;setProperty(&quot;archivesBaseName&quot;, &quot;com.example.myapp-$versionName&quot;)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion &quot;24.0.1&quot;

    defaultConfig {
        applicationId &quot;com.example.myapp&quot;
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 2
        versionName &quot;0.0.2&quot;
        setProperty(&quot;archivesBaseName&quot;, &quot;com.example.myapp-$versionName&quot;)
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'
}

&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Programming</category>
      <category>Android</category>
      <category>playstore</category>
      <category>zipalign</category>
      <category>안드로이드 배포</category>
      <category>플레이스토어</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/10</guid>
      <comments>https://jasonbla.tistory.com/10#entry10comment</comments>
      <pubDate>Mon, 12 Dec 2016 01:07:46 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] CloudBerry Explorer for Amazon S3 사용하기</title>
      <link>https://jasonbla.tistory.com/9</link>
      <description>&lt;p&gt;Amazon의 Remote S3 Storage를 사용하면서 빈번하게 Resource를 update 하다 보면 브라우저로 파일을 일일이 업데이트하기에는 너무 불편한 부분이 많다. 무료 티어를 사용하고 있기도 하고...&amp;nbsp;속도도 느리고 일일이 퍼블리싱하는 것에도 한계가 있기 때문이다. 처음부터 현명하게 AWS 명령줄 인터페이스(aws-shell)를 세팅해놓았으면 좋겠지만 매번 잊어버리기만 하다가... CloudBerry를 알게 되어 설치해보았다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;aws-shell이란? (https://aws.amazon.com/ko/cli/ 참고)&lt;/h4&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;AWS 명령줄 인터페이스(CLI)는 AWS 서비스를 관리하는 통합 도구입니다. 도구 하나만 다운로드하여 구성하면 여러 AWS 서비스를 명령줄에서 제어하고 스크립트를 통해 자동화할 수 있습니다.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/224FDC3D582473D21A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F224FDC3D582473D21A&quot; width=&quot;820&quot; height=&quot;718&quot; filename=&quot;메인.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;다운로드 : http://www.cloudberrylab.com/amazon-s3-explorer-pro-cloudfront-IAM.aspx#close&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;Freeware 버전의 경우 지원되는 부분이 많지는 않지만 Remote Explorer 역할을 톡톡히 해주니 내 경우엔 이 정도로 충분하다고 느꼈다.&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/275D593B582474D31D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F275D593B582474D31D&quot; width=&quot;820&quot; height=&quot;687&quot; filename=&quot;캡처.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 424px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2466763B582476B520&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2466763B582476B520&quot; width=&quot;424&quot; height=&quot;406&quot; filename=&quot;로긴.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;User Name과 Email을 입력하면 Get registration Key가 활성화되고 클릭하면 Email로 registration Key가 발송된다.&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 561px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/262E1C33582476C309&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F262E1C33582476C309&quot; width=&quot;561&quot; height=&quot;472&quot; filename=&quot;s3선택.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;발송된 Registration Key를 입력하고 인증을 완료 후 Cloud Storage를 선택한다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 563px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23461E405824774B0B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F23461E405824774B0B&quot; width=&quot;563&quot; height=&quot;471&quot; filename=&quot;인증키.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;Amazon S3 Account에 연결하기 위해서 Access Key와 Secret Key가 필요한데 AWS의 Account - Security Credential에서 발급할 수 있다.&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;바로가기 : https://console.aws.amazon.com/iam/home?region=us-west-2#security_credential&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2204B845582478B201&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2204B845582478B201&quot; width=&quot;820&quot; height=&quot;359&quot; filename=&quot;시크릿키.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;위 경고대로 이미 발급된 Access Key의 경우 Secret Key를 찾을 수 없기 때문에 'Create New Access Key'를 통해 Access &amp;amp; Secret Key를 새로 발급 받는다. (또는 IAM를 사용하거나)&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;현재 회사 PC에서 2개의 Access Key를 모두 사용 중이어서 더 이상 새로운 Key를 발급받을 수 없다. 어쨌든 여기까지의 과정을 모두 마치면 CloudBerry Explorer를 사용할 수 있게 된다 : )&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/25263B3958247A7411&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F25263B3958247A7411&quot; width=&quot;820&quot; height=&quot;446&quot; filename=&quot;툴 화면.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Programming/Aws</category>
      <category>amazon</category>
      <category>amazon s3</category>
      <category>aws</category>
      <category>Cloud</category>
      <category>cloudBerry</category>
      <category>아마존</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/9</guid>
      <comments>https://jasonbla.tistory.com/9#entry9comment</comments>
      <pubDate>Thu, 10 Nov 2016 22:50:29 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 부분 집합(power set)</title>
      <link>https://jasonbla.tistory.com/7</link>
      <description>&lt;p&gt;본 글은 아래 블로그에서 참고하여 작성한&amp;nbsp;글임을 먼저 밝힙니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;http://dumpsys.blogspot.kr/2015/03/algorithm-binary-counting-power-set.html&lt;/p&gt;
&lt;p&gt;http://hochulshin.com/permutation-composition-summary/&lt;/p&gt;
&lt;p&gt;http://swlock.blogspot.kr/2016/03/power-set.html&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;알고리즘 문제를 풀면서 항상 막히는 부분에 대한 정리가 필요하여 다른 블로그를 참고해 요약을 해보았다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;앞서 정리했던&amp;nbsp;순열 조합 알고리즘과 마찬가지로 문제를 풀다보면 다음과 같이 N개의 숫자로 이루어진 집합에서 &lt;b&gt;부분 집합(Power set)&lt;/b&gt;을 구해야 하는 경우가 종종 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ㅁ 4개의 숫자&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;1, 2, 3, 4&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ㅁ 4개의 숫자로 만들어 낼 수 있는 부분 집합(Power set)&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;2진수 | 원소&lt;/p&gt;
&lt;p&gt;0001 &amp;nbsp;| 1&lt;/p&gt;
&lt;p&gt;0010 &amp;nbsp;| 2&lt;/p&gt;
&lt;p&gt;0011 &amp;nbsp;| 1, 2&lt;/p&gt;
&lt;p&gt;0100 &amp;nbsp;| 3&lt;/p&gt;
&lt;p&gt;0101 &amp;nbsp;| 1, 3&lt;/p&gt;
&lt;p&gt;0110 &amp;nbsp;| 2, 3&lt;/p&gt;
&lt;p&gt;0111 &amp;nbsp;| 1, 2, 3&lt;/p&gt;
&lt;p&gt;1000 &amp;nbsp;| 4&lt;/p&gt;
&lt;p&gt;....(생략)....&lt;/p&gt;
&lt;p&gt;1111 &amp;nbsp;|&amp;nbsp;1, 2, 3 ,4&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;각 집합은&amp;nbsp;중복되지 않는 유일한(Unique) 원소의 조합이므로 비트 연산을 통해 부분 집합을 구할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ㅁ 4개의 숫자(4Bit)로 만들어 낼 수 있는 부분 집합의 수&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;2^4 = 16개&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;16개의 부분 집합이 만들어지는데 각 비트가 1이 되는 자리의 원소를 출력해주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;p&gt;C++ 코드&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;pre class=&quot;brush:csharp&quot;&gt;int main(void)
{
	char arr[MAX] = { '1', '2', '3', '4' };

	/*
	원소의 길이만큼 오른쪽으로 Shift 연산
	Before : 0000 0001
	After    : 0001 0000
	==&amp;gt; 16
	*/
	for (int i = 1; i &amp;lt; (1 &amp;lt;&amp;lt; MAX); i++) {
		for (int j = 0; j &amp;lt; MAX; j++) {
			/*
			AND 연산을 통해 검사할 비트의 자리가 1인 경우에만 해당 원소를 출력
			e.g.
			i == 1, j == 0
			0001 (i)
			0001 (1&amp;lt;&amp;lt;0)
			0001, arr[0] 출력

			i == 1, j == 1
			0001 (i)
			0010 (1&amp;lt;&amp;lt;1)
			0000, 출력X
			*/
			if (i &amp;amp; (1 &amp;lt;&amp;lt; j)) {
				cout &amp;lt;&amp;lt; arr[j] &amp;lt;&amp;lt; &quot;, &quot;;
			}
		}
		cout &amp;lt;&amp;lt; endl;
	}

	return 0;
}
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Programming</category>
      <category>power set</category>
      <category>powerset</category>
      <category>부분 집합</category>
      <category>알고리즘</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/7</guid>
      <comments>https://jasonbla.tistory.com/7#entry7comment</comments>
      <pubDate>Wed, 26 Oct 2016 00:53:36 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 순열 조합</title>
      <link>https://jasonbla.tistory.com/6</link>
      <description>&lt;p&gt;본 글은 아래 블로그에서 참고하여 재정리한&amp;nbsp;글임을 먼저 밝힙니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;font color=&quot;#0066cc&quot;&gt;&lt;u&gt;&lt;a href=&quot;http://gorakgarak.tistory.com/522&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;고락고락 닷컴님의 순열(Permutation) 알고리즘&lt;/a&gt;&lt;/u&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;http://www.eandbsoftware.org/print-all-permutations-of-a-given-string/&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;알고리즘 문제를 풀다보면 다음과 같이 N개의 숫자 중 R개의 숫자를 골라서 만들어낼 수 있는 모든 조합을 구해야 하는 경우가 종종 있다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ㅁ 4개의 숫자&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;1, 2, 3, 4&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;ㅁ 4개의 숫자 중 4가지 숫자로&amp;nbsp;만들어낼 수 있는 조합&amp;nbsp;(중복을 허용하지 않음)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;1, 2, 3, 4&lt;/p&gt;
&lt;p&gt;1, 2, 4, 3&lt;/p&gt;
&lt;p&gt;1, 3, 2, 4&lt;/p&gt;
&lt;p&gt;1, 3, 4, 2&lt;/p&gt;
&lt;p&gt;...&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27436E42580C27C61D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F27436E42580C27C61D&quot; width=&quot;820&quot; height=&quot;370&quot; filename=&quot;캡처.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;출처 : http://www.eandbsoftware.org/print-all-permutations-of-a-given-string/&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;중요한 포인트는, 각 노드에서 스위칭된 원소는 Fixed되어 버리고, Fixed된 원소를 제외한 나머지 원소에 대해 다시 스위칭을 하면서 자식 노드를 뻗어 내려간다는 것이다. (더 이상 스위칭할 원소가 없을때까지)&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;C++ 버전으로 재작성한 코드&lt;br /&gt;&lt;/p&gt;

&lt;pre class=&quot;brush:csharp&quot; style=&quot;margin: 0px; height: 571px; width: 777px;&quot;&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 4
using namespace std;

void swap(int arr[MAX], int i, int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

void print(int arr[MAX], int k) {
	for (int i = 0; i &amp;lt; k; i++) {
		if (i == k - 1) {
			cout &amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; endl;
		}
		else {
			cout &amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; &quot;,&quot;;
		}
	}
}

void perm(int arr[MAX], int currentDepth, int n, int k) {
	if (currentDepth == k) {
		print(arr, k);
		return;
	}

	for (int i = currentDepth; i &amp;lt; n; i++) {
		swap(arr, i, currentDepth);
		perm(arr, currentDepth + 1, n, k);
		swap(arr, i, currentDepth);
	}
}

int main(void)
{
	int arr[MAX] = { 1, 2, 3, 4 };
	int totalOfElement = MAX;
	int outputOfElement = MAX;
	perm(arr, 0, totalOfElement, outputOfElement);

	return 0;
}

&lt;/pre&gt;&lt;div&gt;&lt;font face=&quot;monospace&quot;&gt;&lt;span style=&quot;font-size: 13.3333px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;C++ STL 활용&lt;/p&gt;

&lt;pre class=&quot;brush:csharp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#define MAX 4
using namespace std;

int main(void)
{
	int arr[MAX] = { 1, 2, 3, 4 };
	
	do {
		for (int i = 0; i &amp;lt; MAX; i++) {
			cout &amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; &quot;,&quot;;
		}
		cout &amp;lt;&amp;lt; endl;
	} while (next_permutation(arr, arr + MAX));

	return 0;
}
&lt;/pre&gt;&lt;/div&gt;</description>
      <category>Programming</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/6</guid>
      <comments>https://jasonbla.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 23 Oct 2016 02:46:41 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] Amazon S3 Service 이용 시 Favicon error 해결하기(Forbidden Error)</title>
      <link>https://jasonbla.tistory.com/5</link>
      <description>&lt;p&gt;Amazon의 S3 Storage를&amp;nbsp;이용하다 보면 해당 Bucket의 Root Directory에 Favicon.ico를 업로드 하였음에도 불구하고 다음과 같은 에러가 나는 경우가 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Failed to load resource: the server responded with a status of 403 (Forbidden)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2773BA4F57F515042C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2773BA4F57F515042C&quot; width=&quot;820&quot; height=&quot;110&quot; filename=&quot;Screen Shot 2016-10-05 at 11.15.26 PM.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;S3의 Root에 Favicon.ico가 없다는 건 당연히 알겠는데.. S3의 Root에서는 오로지 Bucket 생성만 가능한데 어떻게 Favicon을 추가하란 이야기인지 이해가 안 돼서 계속 구글링하다가 답변을 얻게 됨.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;참고 링크&lt;/b&gt;&lt;/p&gt;&lt;p&gt;https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/dev/VirtualHosting.html&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;사용자 지정 URL 외에도&amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: rgb(9, 0, 255);&quot;&gt;가상 호스팅의 또 다른 장점은 버킷 가상 서버의 &quot;루트 디렉터리&quot;에 게시할 수 있는 기능&lt;/span&gt;&lt;/b&gt;입니다. 이 기능은 기존의 많은 애플리케이션이 이 표준 위치에서 파일을 검색하기 때문에 중요할 수 있습니다.&lt;/p&gt;&lt;/blockquote&gt;&lt;h4&gt;결론부터...&lt;/h4&gt;&lt;p&gt;결론부터 이야기하면 Bucket의 가상 호스팅(Virtual Hosting)을 이용하면 해당 리소스(Favicon, Robot.txt, crossdomain.xml&amp;nbsp;등)를 Bucket의 Root Directory에 게시할 수 있다. &amp;nbsp;따라서, 해당 Bucket의 Root Directory에 Favicon (또는 다른 리소스)을 업로드하고, 가상 호스팅 도메인으로 접속을 하면 Favicon 에러는 사라지게 된다.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) Bucket의&amp;nbsp;Root Directory에 Favicon 업로드&lt;/div&gt;&lt;div&gt;2) 가상 호스팅 도메인 접속&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;h4&gt;알아두기&lt;/h4&gt;&lt;p&gt;Amazon S3는 모든 지역(리젼)에서 버킷 액세스에 대해 다음 두 가지 방식을 지원한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1) 가상 호스팅 방식 액세스&lt;/p&gt;&lt;p&gt;2) 경로 방식 액세스&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;가상 호스팅(Virtual Hosting) 액세스란?&lt;/h4&gt;&lt;p&gt;단일 웹 서버로부터 여러 웹 사이트를 제공하는 것.&lt;/p&gt;&lt;p&gt;AWS의 S3 서비스에서 가상 호스팅 예를 들자면..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;AWS S3 service URL : https://s3-us-west-2.amazonaws.com/ 이고,&lt;/p&gt;&lt;p&gt;Bucket1, Bucket2가 존재할 때 다음과 같이 가상 호스팅이 가능하다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1) https://&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Bucket1&lt;/span&gt;.s3-us-west-2.amazonaws.com/&lt;/p&gt;&lt;p&gt;2) https://&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Bucket2&lt;/span&gt;.s3-us-west-2.amazonaws.com/&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;경로 방식 액세스란?&lt;/h4&gt;&lt;p&gt;URI의 경로 이름 부분으로 호스트를 구분하는 것.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1) https://s3-us-west-2.amazonaws.com/&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Bucket1&lt;/span&gt;/...&lt;/p&gt;&lt;p&gt;2) https://s3-us-west-2.amazonaws.com/&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Bucket2&lt;/span&gt;/...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Programming/Aws</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/5</guid>
      <comments>https://jasonbla.tistory.com/5#entry5comment</comments>
      <pubDate>Thu, 6 Oct 2016 00:32:22 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 스프링 버전 확인</title>
      <link>https://jasonbla.tistory.com/4</link>
      <description>&lt;h4&gt;1. 프로젝트에서 스프링 현재 버전 확인&lt;/h4&gt;&lt;p&gt;Pom.xml에서 Dependencies 모듈을 통해 스프링의 버전을 확인할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 400px; width: 400px; height: 197px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2329E85057F0B90217&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2329E85057F0B90217&quot; width=&quot;400&quot; height=&quot;197&quot; filename=&quot;Screen Shot 2016-10-02 at 4.35.21 PM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 400px; height: 197px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;2. 스프링 최신 버전 확인&lt;/h4&gt;&lt;p&gt;https://projects.spring.io/spring-framework/&lt;/p&gt;</description>
      <category>Framework/Spring</category>
      <category>버전</category>
      <category>스프링</category>
      <category>스프링버전</category>
      <author>jason hwang</author>
      <guid isPermaLink="true">https://jasonbla.tistory.com/4</guid>
      <comments>https://jasonbla.tistory.com/4#entry4comment</comments>
      <pubDate>Sun, 2 Oct 2016 16:40:09 +0900</pubDate>
    </item>
  </channel>
</rss>