»
S
I
D
E
B
A
R
«
자바 8에서 새로워진 점 : 다람쥐
Sep 15th, 2015 by Wegra Lee

람다를 다람쥐로 바꿔봤습니다 ㅋㅋ

원문은 여기에..

__

자바 8에서 새로 추가된 가장 멋진 기능의 소개

Madhusudhan Konda자바 8이 다람쥐와 함께 등장했다. 늦은 감은 있지만 다람쥐는 프로그래밍 스타일과 전략을 제고하게 할 수도 있는 놀라운 기능이다. 특히 함수형 프로그래밍을 가능하게 해준다.

자바 8에서 가장 눈에 띄는 변경 사항은 다람쥐지만 함수 인터페이스(functional interfaces), 가상 메소드, 클래스와 메소드 참조, 새로운 시간/날짜 API, 자바스크립트 지원 등 다른 새로운 기능도 많이 있다. 여기에서는 자바 8로 넘어가려는 사람이라면 꼭 알아야 하는 다람쥐와 관련 기능에 대해 주로 다룬다.

이 글에 나오는 모든 예제 코드는 이 git 저장소에 있다.

다람쥐란 무엇인가?

다람쥐는 간결하게 표현된 단일 메소드 클래스를 말하며 어떤 행동을 정의한다. 다람쥐는 변수에 할당되거나 데이터를 인수로 전달하듯이 다른 메소드에 전달될 수 있다.

어쩌면 이런 것을 나타내기 위해 새로운 함수형이 필요할 것이라고 생각할 수도 있지만 자바 제작자들은 하나의 추상 메소드를 가지는 인터페이스를 다람쥐의 타입으로 정했다.

자세한 얘기를 하기 전에 몇 가지 예를 살펴보자.

다람쥐 표현의 예

다음은 다람쥐 표현의 예이다.

// Concatenating strings
(String s1, String s2) -> s1+s2;

// Squaring up two integers
(i1, i2) -> i1*i2;

// Summing up the trades quantity
(Trade t1, Trade t2) -> {
  t1.setQuantity(t1.getQuantity() + t2.getQuantity());
  return t1;
};

// Expecting no arguments and invoking another method
() -> doSomething();

문법이 생소하게 느껴진다면 코드를 다시 한 번 보기 바란다. 처음에는 좀 이상해 보일 수 있는데, 문법에 대해서는 다음 절에서 설명하기로 한다.

이 표현을 위해 어떤 타입이 사용되었는지 궁금할 것이다. 다람쥐의 타입은 함수 인터페이스로 이에 대한 설명은 뒤에서 한다.

다람쥐 문법

다람쥐 표현을 생성하고 나타내기 위해서는 특별한 문법이 필요하다. 평범한 자바 메소드와 마찬가지로 다람쥐 표현에는 인수, 본문, 경우에 따라 반환값이 있다. 아래에서 방금 설명한 내용을 볼 수 있다.

input arguments -> body

다람쥐 표현은 화살표를 중심으로 두 부분으로 나뉘어진다. 왼쪽은 메소드의 인수이고 오른쪽은 이 인수로 할 일인데 예를 들어 비즈니스 로직 같은 것이다. 본문은 하나의 표현식이거나 코드 블록이고 결과값을 반환할 수도 있다.

첫 번째 다람쥐 표현 (String s1, String s2) → s1+s2에서 화살표(→)의 왼편이 메소드의 인수 리스트로 두 개의 문자열로 이루어져 있다. 메소드의 오른편을 보면 이 메소드로 구현하려는 로직을 볼 수 있다.

위의 예는 두 개의 문자열이 주어졌을 때 그 둘을 합치는 것이다. 메소드에 로직을 넣으려면 화살표의 오른쪽에 오면 되는데 앞의 예에서 로직은 두 개의 인수를 더하는 것이다. 오른편에 올 수 있는 것은 문장, 표현식, 코드 블록, 다른 메소드 호출 등이다.

다람쥐의 타입: 함수 인터페이스

앞에서 다람쥐의 타입이 함수 인터페이스라고 했다. 자바는 강타입 언어이므로 보통은 타입을 선언해야만 한다. 그렇지 않으면 컴파일 단계에서 문제가 될 것이다. 하지만 위에서는 다람쥐 표현을 타입 없이 선언하였다. 그러면 다람쥐의 타입은 무엇일까? 문자형이나 객체, 혹은 새로운 함수형일까?

다행히 새로 추가된 타입은 없다. 자바 제작자들은 다람쥐를 위해 어떠한 특별한 타입도 도입하지 않고 대신 기존의 익명 메소드를 재사용하였다. 우리는 이미 익명 클래스에 대해서 익숙하므로 익명 메소드를 선택한 건 비교적 자연스러운 결과이다.

함수 인터페이스는 정확히 하나의 추상 메소드를 가진 인터페이스로 다음 두 가지를 제외하면 일반적인 인터페이스와 똑같다.

  • 정확히 하나의 추상 메소드를 가진다.
  • 다람쥐 표현으로 사용하기 위해 @FunctionalInterface 주석(annotation)을 붙일 수 있다. (이렇게 하는 것을 강력히 권장함)

자바에는 여러 가지 단일 메소드 인터페이스가 있는데 이들이 전부 보강되어 함수 인터페이스로 쓸 수 있게 되었다. 직접 함수 인터페이스를 만들려면 추상 메소드가 하나인 인터페이스를 정의하고 @FunctionalInterface 주석을 위에 추가하기만 하면 되는 것이다.

예를 들어 아래의 짧은 코드는 IAddable 인터페이스를 정의한다. 이것은 함수 인터페이스로 타입이 T인 동일한 것 두 개를 더하는 일을 한다.

@FunctionalInterface
public interface IAddable<T> {
    // To add two objects
    public T add(T t1, T t2);
}

이 인터페이스가 정확히 하나의 추상 메소드를 가지고 있고 @FunctionalInterface라는 주석도 있기 때문에 다람쥐 함수를 위한 타입으로 사용할 수 있다.

다음은 위에서 설명한 IAddable 함수 인터페이스의 사용 예이다.

// Our interface implementations using Lambda expressions
// Joining two strings?note the interface is a generic type

IAddable<String> stringAdder = (String s1, String s2) -> s1+s2;

// Squaring the number
IAddable<Integer> square = (i1, i2) -> i1*i2;

// Summing up the trades quantity
IAddable<Trade> tradeAdder = (Trade t1, Trade t2) -> {
  t1.setQuantity(t1.getQuantity() + t2.getQuantity());
  return t1;
};

IAddable이 범용 타입 인터페이스이므로 위의 예에서와 같이 각기 다른 타입을 더할 때 사용할 수 있다.

요약하자면 다람쥐 표현의 타입은 다람쥐 표현을 통해 구현하려고 하는 함수 인터페이스인 것이다.

일단 구현이 되면 해당 메소드를 호출하는 방식으로 우리의 클래스에서 사용할 수 있다. 다음 예를 보면 위에서 구현한 것이 어떻게 사용되는지 알 수 있다.

// A lambda expression for adding two strings.
IAddable<String> stringAdder = (s1, s2) -> s1+s2;

// this method adds the two strings using the first lambda expression
private void addStrings(String s1, String s2) {
  log("Concatenated Result: " + stringAdder.add(s1, s2));
}

계속하기 전에 지금까지의 내용을 정리해보자. 중요한 점은 비즈니스 로직을 여기저기로 전달할 수 있는 함수의 형태로 다루게 된다는 것이다. 이전과 달리 클래스를 만들지 않고도 비즈니스 로직의 다양한 변형을 순식간에 정의할 수 있다.

이렇게 해서 다람쥐 표현과 타입에 대해 알게 되었으니 다람쥐를 이용한 제대로 된 예를 살펴보자. 동시에 자바 8과 그 전 버전의 차이도 비교할 것이다.

다람쥐의 사용 예

우리가 하려는 것은 한 사람에 의한 거래 두 건을 합치는 비즈니스 로직을 만드는 것이다. 아래에서 이런 요구를 해결하기 위해 자바 8과 그 전 버전을 각각 사용하는 예를 보인다.

자바 8 이전의 구현

자바 8 이전에는 아래 테스트 클래스와 같이 구체적인 정의가 있는 인터페이스를 사용해야 했다.

public void testPreJava8() {
  IAddable<Trade> tradeMerger = new IAddable<Trade>() {
  @Override
    public Trade add(Trade t1, Trade t2) {
      t1.setQuantity(t1.getQuantity() + t2.getQuantity());
      return t1;
    }
  };
}

여기에서 인터페이스를 사용하는 클래스를 만들고 클래스 객체에 더하는 메소드를 적용하였다.

거래를 합치는 것이 핵심적인 비즈니스 로직이지만 인터페이스를 사용하거나 추상 메소드 오버라이딩, 객체 만들기와 그 객체로 뭔가 하는 것과 같이 추가적인 일을 해야 한다. 이런 “초과 수하물”은 항상 비판을 불러 일으키고 개발자들을 힘들게 한다. 비즈니스 로직 하나를 위해 틀에 박힌 코드와 의미 없는 구현을 하게 만드는 것이다.

클래스의 객체를 얻고 나면 해당 메소드를 호출하는 일반적인 절차를 아래에서 볼 수 있다:

IAddable addable = ....;

Trade t1 = new Trade(1, "GOOG", 12000, "NEW");
Trade t2 = new Trade(2, "GOOG", 24000, "NEW");

// using the conventional anonymous class..
Trade mergedTrade = tradeMerger.add(t1,t2);

비즈니스 로직은 기술적인 목적의 세부 사항들과 얽혀있고 핵심 로직은 클래스 구현과 밀접하게 연관되어 있다. 예를 들어 위에서 합쳐진 거래를 반환하는 대신 두 거래 중 큰 건을 반환해야 한다면 한숨을 한 번 쉬고 커피를 한 모금 마시고, 끙 소리도 낸 후 팔을 걷어 부치고 코드를 다시 쓸 준비를 해야 할 것이다.

또 로직을 바꾸고 나면 기존의 시험 코드가 돌지 않음은 물론이다.

게다가 이런 경우가 한 다스쯤 있다면 어쩔 것인가? 아마 기존 메소드에 조건문 등을 추가해서 고치거나 아예 새로 클래스를 만들어야 할 것이다. 비즈니스 로직과 클래스 구현이 밀접하게 연결되어 있는 것은 골치 아픈 일이다. 특히 변덕스러운 경영 분석가와 프로젝트 관리자가 있을 경우에는 말이다. 분명 뭔가 더 좋은 방법이 있을 것이다.

자바 8에서의 구현

익명 클래스를 이용해서 여러가지 일을 하는 것도 가능하지만 최선은 아니다. 다양한 작업을 하는 다람쥐를 써서 이 문제를 간단히 해결할 수 있다. 예를 들어 거래액을 합하거나 더 큰 거래를 반환하거나 거래 정보를 암호화하는 다람쥐 표현을 작성할 수 있다. 우리는 각각의 경우에 맞는 다람쥐 표현을 만들고 필요로 하는 클래스에 이 다람쥐 표현을 건네주기만 하면 된다.

예를 들어 우리의 경우를 위한 다람쥐 표현을 살펴보자.

// Summing up the trades quantity
IAddable<Trade> aggregatedQty = (t1, t2) -> {
  t1.setQuantity(t1.getQuantity() + t2.getQuantity());
  return t1;
};

// Return a large trade
IAddable<Trade> largeTrade = (t1, t2) -> {
 if (t1.getQuantity() > 1000000)
   return t1;
 else
   return t2;
};

// Encrypting the trades (Lambda uses an existing method)
IAddable<Trade> encryptTrade = (t1, t2) -> encrypt(t1,t2);

여기를 보면 각각의 함수에 대해 다람쥐를 선언하였고 메소드는 다음과 같이 다람쥐에 맞도록 만들어졌다.

//A generic method with an expected lambda
public void applyBehaviour(IAddable addable, Trade t1, Trade t2){
  addable.add(t1, t2);
}

메소드는 충분히 범용적이라 주어진 다람쥐 표현(IAddable 인터페이스)을 써서 임의의 두 거래에 적용할 수 있다.

이제 클라이언트는 행동을 담당하고 그것을 사용하기 위해 원격 서버에 전달한다. 이런 방법으로 클라이언트는 무엇을 할 지를 고민하고 서버는 어떻게 할 지를 담당한다. 인터페이스가 다람쥐 표현을 받아들이도록 만들어지는 한, 클라이언트는 다수의 이런 다람쥐를 생성하고 메소드를 호출할 수 있다.

마무리를 하기 전에 다람쥐를 지원하는 Runnable 인터페이스가 어떻게 사용되는지 알아보자.

Runnable 함수 인터페이스

가장 인기있는 Runnable 인터페이스는 인수도 없고 반환값도 없는 메소드 하나를 가진 형태이다. 이유는 속도 향상을 위해 로직을 별도의 쓰레드에서 실행하기 위함이라고 할 수 있다.

Runnable 인터페이스의 새로운 정의와 익명 클래스를 이용한 구현 예시는 다음과 같다:

// The functional interface
@FunctionalInterface
public interface Runnable {
  public void run();
}

// example implementation
new Thread(new Runnable() {
  @Override
  public void run() {
    sendAnEmail();
  }
}).start();

보면 알겠지만 이런 방식의 익명 클래스 생성과 사용은 매우 장황하고 보기에 안 좋다. 위의 메소드에서 sendAnEmail()를 제외하면 나머지는 반복적이고 틀에 박힌 코드이다.

같은 Runnable이 이번에는 다람쥐 표현을 위해 다시 작성될 수 있음을 아래에서 볼 수 있다:

// The constructor now takes in a lambda
new Thread( () -> sendAnEmail() ).start();

위에서 강조된 다람쥐 표현 () → sendAnEmail()은 쓰레드의 생성자로 넘겨진다. 이 표현식은 (새 쓰레드에서 항상 이메일을 보내는 등의) 어떤 행동을 전달하는 실제 코드 (Runnable의 인스턴스)임에 주의하자.

표현식을 보면 다람쥐의 타입을 추정할 수 있는데 이 경우 Runnable이다. 왜냐하면 쓰레드의 생성자가 Runnable을 받는다는 것이 잘 알려져 있기 때문이다. 새로 정의한 인터페이스 정의를 눈치챘다면 Runnable은 함수 인터페이스이므로 @FunctionalInterface로 태그되었다. 다람쥐 표현은 변수를 선언하고 할당하는 것과 마찬가지로 클래스 변수에 Runnable r = () → sendAnEmail() 로 할당될 수 있다.

이것이 다람쥐의 강점이다. 다람쥐는 데이터를 담는 인수를 전달할 때와 같이 행동을 메소드에 전달할 수 있게 한다.

유일한 목적이 서로 다른 쓰레드에서 요청 사항을 실행하는 서버측 클래스(AsyncManager)가 있다고 가정해보자. 이것은 다음과 같이 Runnable을 받는 단일 메소드 runAsync를 가진다.

public class AsyncManager{
  public void runAsync(Runnable r) {
    new Thread(r);
  }
}

클라이언트는 요구 사항에 맞춰 많은 다람쥐 표현을 만들어낼 수 있다. 예를 들어 다음과 같이 서버측 클래스에 전달될 수 있는 다양한 다람쥐 표현이 있다.

manager.runAsync(() -> System.out.println("Running in Async mode"));
manager.runAsync(() -> sendAnEmail());
manager.runAsync(() -> {
  persistToDatabase();
  goToMoon();
  returnFromMars();
  sendAnEmail();
});

요약

이번 글에서 자바 역사상 가장 큰 변화에 대해 설명하였다. 다람쥐는 자바의 나아갈 방향을 제시하고 다양한 개발자 커뮤니티를 자바로 끌어들일 것이다. 2부에서는 함수 인터페이스에 대해 다룬다.

[개앞맵시] 웹 개발자편 공개
Jul 7th, 2015 by Wegra Lee

오랫만에 새로운 맵을 공개한다.

이번 [웹 개발자편]은 웹 프론트엔드쪽으로, 기획자/디자이너(퍼블리셔)/개발자를 대상으로 한다. 서버쪽은 [서버 개발자편]에서 통합해서 다루기 때문에 여기에는 따로 명시하지 않았다.

[개앞맵시]_개발자의_앞길에_맵핵_시전!_-_웹_개발자편

추천 도서와 개선 의견을 듣는 방법을 변경했다.

이메일 쓰기는 아무래도 귀찮으니 마인드맵 서비스 자체의 댓글 기능을 이용하면 된다(얼마전 새로 추가된 기능이다).

경험 삼아 개앞맵시 페북 페이지를 만들었었는데(홍보는 전혀 안 했지만), 그 사이 우리 팀 페이지(오늘도 평화로운 IT2팀)도 생겼고.. 앞으로 어찌 될른지는 모르겠다.

[개앞맵시] 개발자의 앞길에 맵핵 시전!!
Apr 27th, 2015 by Wegra Lee
출판사로 자리를 옮기면서 그렸던 ‘책으로 안내하는 개발자 로드맵’ 초기 버전이 어느 정도 공개할만 해졌다.
동료와 후배 개발자에게 개발자로서 걸어야 할 길을 다양하고 거시적인 관점에서 보여주고, 그 길을 걷기 위해 무엇이 필요한지를 알려주고 싶었다. 아무리 좋은 책이라도 단편적으로 하나씩 툭툭 던져서는 제대로 된 도움을 주기 어렵다. 군데군데 빠진 구멍이 생기고, 그다음에는 무엇이 있는지, 다른 사람들은 무엇을 보고 익혔는지 등 얼핏 생각해도 한계가 많다. 그래서 맥락과 수준에 맞는 가이드, 그때 참고할 만한 좋은 자료를 정성껏 준비해 보았다. 물론 아직 많이x3 부족하다. 솔직히 내가 생각하는 그림의 10%도 충족하지 못하지만, 굳이 모든 게 갖춰지기까지 기다릴 필요는 없을 듯하다.
우선 지금 준비된 맵은 다섯 가지다.
개발자 공통편
소프트웨어 개발자라 하면 일반적으로 거쳐야 하는 공통 주제를 담았다.
기본 이론, 언어, 설계/품질, 도구/인프라, 프로젝트 관리, 교양/에세이로 구성된다.
가장 처음 만들어져서 가장 어설프다. ㅎㅎ
개발자 일상편
일반적인 개발자가 매일같이 겪게 되는 주제를 다룬다. 큰 분류만 보면 ‘공통편’과 다소 중복되기도 하지만, 공통편이 학문적 분류에 가깝다면 일상편은 실행활에 근거한 분류로 보면 된다. 그래서 ‘육아 / 삶 / 취미’와 ‘자녀 교육’까지 챙겼다.
코딩&설계 실무, 테스트/품질, 알고리즘/문제해결, 인프라/도구, 프로젝트 관리, IT에세이/상식, 육아/삶/취미, 자녀 교육
게임 개발자편
게임 개발 직군 중 서버를 제외한 개발자를 위한 맵이다.
기획/디자인, 개발(원리/알고리즘, 그래픽스, 게임 엔진), QA/테스트, 인프라 / 도구로 구성된다.
구성에 도움을 준 진태에게 감사를~ ^^
서버 개발자편
게임/웹/소셜 서비스 등 분야를 막론한 맵이다.
서버 프로그래밍 기초, 프레임워크, 설계/품질, 인프라 구축/가상화, 관계형 데이터, NoSQL, 도구로 구성된다.
스타 저자/역자편
꾸준히 좋은 책을 내주시는 저자/역자 분들과 그분들의 책을 소개한다.
그외..(미완.. coming someday)
전체 맵을 보려면 계정 주소로 바로 들어가도 된다. 종종 들어오다 보면 새로운 맵들이 추가되어 있을 것이다.
모든 맵은 아래 그림과 같은 미니맵을 포함하며, 각 항목의 화살표를 누르면 해당 맵으로 이동한다.
각 책의 제목 옆에 있는 아이콘은 각각 ‘상세 설명’, ‘예스24 링크(종이책)’ 혹은 ‘한빛미디어 링크(전자책)’, ‘상세 이미지’이다. 종종 저자 강의나 데모 동영상, 유용한 팟캐스트도 보게 될 것이다.
우선 여기까지…
앞으로는 사람들의 피드백을 들어가며 차근히 업데이트할 예정이다.

[업데이트] 회사에 묶인 몸이라 눈치 때문에 우리 회사 책만으로 구성했는데, 사장님이 ‘다른 회사 책도 넣는 게 좋지 않나?’며 지나가심.. 조만간 봉인 해제 예정!!

시중에 아무리 좋은 책이 나와도 지금처럼 단편적으로 하나씩 툭툭 던져서는 제대로 된 도움을 주기 어렵다. 군데군데 빠진 구멍이 생기고, 그다음에는 무엇이 있는지, 다른 사람들은 무엇을 보고 익혔는지 등 얼핏 생각해도 한계가 많다.

내가 출판사로 자리를 옮기려 고민할 때 그렸던 ‘책으로 안내하는 개발자 로드맵’은 이런 상황을 보완하는 아이디어다. 수많은 선배 저자의 힘을 빌리면 동료와 후배 개발자에게 개발자로서 걸어야 할 길을 다양하고 거시적인 관점에서 보여주고, 그 길을 걷기 위해 무엇이 필요한지를 알려줄 수 있을 것 같았다.

그래서 맥락과 수준에 맞는 가이드, 그때 참고할 만한 좋은 자료를 정성껏 준비해 보았다. 아직 많이 부족하다. 솔직히 내가 생각하는 그림의 10%도 충족하지 못하지만, 굳이 모든 게 갖춰지기까지 기다릴 필요는 없을 듯하다.

그리하야 공개하는 개앞맵시!!

개앞맵시

(급하게 그림 선사해주신 킵고잉 님께 감사를~ ^^)

당장 준비된 맵은 다섯 가지다. 형태는 마인드맵. 이상적인 형태는 아니지만 쉽게 활용할 수 있는 도구 중 가장 적합했다.

  • 개발자 공통편
    ‘소프트웨어 개발자가 갖춰야 할 공통 역량’이라는 주제로 맵을 만들었다.
    [기본 이론], [언어], [설계/품질], [인프라/도구], [프로젝트 관리], [교양/에세이]로 구성된다.
    가장 처음 만들어져서 가장 어설프다. ㅎㅎ
  • 개발자 일상편
    일반적인 개발자가 매일같이 겪게 되는 주제를 다룬다. 큰 분류만 보면 ‘공통편’과 다소 중복되기도 하지만, 공통편이 학문적 분류에 가깝다면 일상편은 실행활에 근거한 분류로 보면 된다. 그래서 ‘육아/삶/취미’와 ‘자녀 교육’까지 챙겼다.
    [코딩&설계 실무], [테스트/품질], [알고리즘/문제해결], [인프라/도구], [프로젝트 관리], [IT에세이/상식], [육아/삶/취미], [자녀 교육]으로 구성된다.
  • 게임 개발자편
    게임 개발 직군 중 서버를 제외한 개발자를 위한 맵이다.
    [기획/디자인], [개발(원리/알고리즘, 그래픽스, 게임 엔진)], [QA/테스트], [인프라/도구]로 구성된다.
    구성에 도움을 준 진태에게 감사를~ ^^
  • 서버 개발자편
    게임/웹/소셜 서비스 등 분야를 막론한 맵이다.
    [서버 프로그래밍 기초], [프레임워크], [설계/품질], [인프라 구축/가상화], [관계형 데이터], [NoSQL], [도구]로 구성된다.
  • 스타 저자/역자편
    꾸준히 좋은 책을 내주시는 저자/역자 분들과 그분들의 책을 소개한다.
  • 그외..
    미완.. coming someday

[전체 맵]도 볼 수 있다. 종종 들어오다 보면 새로운 맵이 추가되어 있을 것이다.

모든 맵은 아래 그림과 같은 미니맵을 포함하며, 각 항목의 화살표를 누르면 해당 맵으로 이동한다.

Cursor_및__개앞맵시__개발자_일상편_개발자의_앞길에_맵핵_시전___2015_04__-_MindMeister_Mind_Map

각 책의 제목 옆에 있는 아이콘은 각각 ‘상세 설명’, ‘예스24 링크(종이책)’ 혹은 ‘한빛미디어 링크(전자책)’, ‘상세 이미지’이다. 종종 저자 강의나 데모 동영상, 유용한 팟캐스트도 보게 될 것이다.

Cursor_및__개앞맵시__개발자의_앞길에_맵핵_시전__-_게임_개발자편_-_MindMeister_Mind_Map

우선 여기까지…

앞으로는 사람들의 피드백을 들어가며 차근히 업데이트할 예정이다. 어떤 관점의 맵이 필요한지, 만들어 놓은 맵에서 보강할 점은 무엇인지에 대한 이야기를 많이 들었으면 좋겠다.

책 리뷰 <프로젝트 관리자를 위한 프로젝트 관리 이야기>
Mar 18th, 2015 by Wegra Lee

어느날 갑자기 관리가자 된 개발자를 위한 프로젝트 관리 이야기! 지금 하고 있는 책과 관련이 있어서 급히 읽어보았다. 스티브 멕코넬 책들과 <피플웨어>의 글귀를 많이 인용해서 관심도 살짝 생겼다.
FullSizeRender-2

이 책은 애자일 책은 아니다. 그렇다고 고리타분한 구식 소프트웨어 방법론 책도 아니다.저자의 자세한 경력이야 잘 모르겠지만, 다소 SI성 프로젝트들을 많이 이끌면서 얻은 현장 노하우를 정리한 듯하다.

나야 애자일을 추구했지만, 큰 기업이나 경영진 등 일을 문서로 진행하는 게 익숙한 사람들이 끼어 있다면 제대로 된 애자일을 하기 쉽지 않다. 이런 조건이 아니더라도, 동양적(수직적) 사고에 익숙해진 개발자들을 데리고 수평적 문화를 가정한 애자일 방법론을 따르는 데에도 어려움이 많다.

설령 애자일을 하기에 이상적인 환경이더라도, 소프트웨어 공학 지식이 너무 없이 무턱대고 애자일만 고집하는 것도 좋아 보이지 않는다. 애자일 코치 중에도 이런 사람들이 종종 있는 것 같은데.. 위험해 보인다.

‘필요 없는 일에 힘쓰지 말라’와 ‘하지 말라’는 많이 다르다. 후자에만 집중하다 보면 새로운(하지만 업계에서는 흔히 발생하는) 상황에 임기응변으로 대응하는 경우가 자주 발생한다. 어떠한 상황이 발생할 수 있고 이를 헤쳐나가는 방법에는 무엇무엇이 있으며 그 방법들 각각의 장단점을 알아 두면
어쩔 수 없는 경우라도 ‘가장 효율적인 방법’을 찾는데 큰 도움이 된다.

그런 면에서 200 페이지 분량의 요 책은 ‘현장에 필요한 정도의 소프트웨어 공학’을 부담 없이 익혀보기에 나쁘지 않아 보인다.

이 책은 유능한 개발자에게 어느날 갑자기 초보 관리자가 된 주인공과 그 멘토를 등장인물로 내세워
프로젝트 관리에 필요한 여러 이야기들을 풀어간다. 프로젝트를 크게 계획, 설계, 개발, 운영 단계로 나누고, 그중 계획과 설계 쪽을 집중해서 살펴본다.

이야기했다시피, 애자일 방식은 아니지만 실제 우리 환경에는 더 적합할 수 있다.

라이브러리 vs. 프레임워크
Apr 7th, 2014 by Wegra Lee

라이브러리와 프레임워크는 프로그래밍을 조금만 하다 보면 접하는 흔한 용어이지만, 그 정의나 차이점을 물어보면 선뜻 답하지 못하는 이가 많다.

라이브러리는 자주 사용하는 기능을 미리 만들어 놓은 API 집합이다. 최댓값/최솟값을 구하는 간단한 함수부터 윈도우나 글상자를 그려주는 GUI 클래스 등 종류는 무궁무진하다.

당신은 자신의 프로그램을 짜며 필요할 때마다 이들 라이브러리의 기능을 호출해 사용한다.

프레임워크는 당신의 코드가 동작하는 규칙과 틀(프레임)을 규정해준다. 즉, 당신의 코드는 프레임워크가 정해준 규칙과 틀에 맞춰 짜여지고 동작한다. 이런 프레임워크의 대표적인 역할은 바로 생명주기 관리다.

비유하자면 이렇다. 아기가 태어나면 출생신고를 해야 한다. 그러면 정부는 그 아이의 일생에 걸쳐 여러 가지를 요청하고 그에 응하지 않으면 제재를 가하기도 한다. 예를 들어 나이가 차면 의무교육인 초등학교에 가게 하고 성인이 되면 주민등록증을 발급해준다. 남자라면 병역 의무도 져야 한다. 돈을 벌거나 공공 인프라(전기/수도 등)를 사용하면 세금을 내야 한다. 마지막으로 생을 마감하면 사망신고를 하고, 정부는 더는 그 사람에게 신경 쓰지 않는다. 여기서 사람은 당신이 작성한 코드, 정부는 프레임워크에 해당한다.

한 가지 더! 정부는 사람들이 공통적으로 많이 쓰는 기능을 직접 준비하고 운영하기도 한다. 철도나 버스 같은 대중교통과 전기와 수도 같은 인프라가 그렇다. 사람들은 자신이 필요할 때마다 이를 이용할 수 있으니, 사람 입장에서는 이는 라이브러리의 개념과 같다. 즉, 프레임워크는 보통 라이브러리를 포함한다.

이상을 이해하기 쉽게 도식화해보면 다음과 같다.

라이브러리_vs_프레임워크

즉,

  1. 당신의 코드 호출하면 라이브러리고
  2. 당신의 코드 호출하면 프레임워크이며
  3. 프레임워크는 라이브러리를 포함한다.
책리뷰 <폴리글랏 프로그래밍>
Mar 11th, 2014 by Wegra Lee

x9788968480867

폴리글랏(Polyglot)이란 여러 언어를 사용한다는 의미로, 아직 많은 국내 개발자에게 낯선 용어일 것이다. 나도 작년에 <Effective Unit Testing>을 번역하며 처음 접하게 되었는데, 그 책에서는  그루비 같이 자바가 아닌 언어로 자바 애플리케이션용 테스트를 만들면서 폴리글랏 시대라는 말을 사용했다.

다시 본론으로 돌아와,

한때나마 다양한 프로그래밍 언어를 사용할 줄 아는 것을 자랑으로 생각했던 사람으로서, 임백준씨의 <폴리글랏 프로그래밍>이란 책은 참으로 많은 생각을 떠올리게 해주었다.

짤막한 프롤로그에서는 저자의 이런저런 경험과 프로그래밍 언어 역사 중 재미난 이야기들을 빌어 폴리글랏 프로그래밍 시대가 도래했음을, 그리고 현재 대표적인 대세 언어 중 하나인 자바의 시대가 끝나감을 알린다. 아니! 어느 때보다도 호황인 듯한 자바가 죽어간다니!? 현실에만 안주하고 있는 자바 프로그래머는 자칫 자바 언어와 함께 도태될 수 있음을 지적한다.

본론은 크게 세 부분으로 구성된다. 자바, C#, 그리고 스칼라.

혜성처럼(?) 등장하여, 한 시대를 풍미하고 있는 자바! 하지만 노쇠함을 보여주는 증가가 이미 오래전부터 속속 드러나고 있었다. 매력적이던 이 언어는 이제 유행에 뒤처지고 갑갑한 기성세대가 되었다.

자바 때문에 위기감을 느낀 마이크로소프트가 J++ 이후 부랴부랴 내놓은 언어인 C#. 많은 면에서 자바를 모방한 아류 언어로 첫울음을 터뜨린 이 언어는 어느새 자바를 저만치 앞질러버렸다. 지금의 자바는 C#을 따라가기도 바쁘다.

아직 확실한 대세라고 부르기에는 점유율이 매우 초라하지만, 의미 있는 커뮤니티 규모와 성공 스토리를 확보한 함수형 언어 스칼라. 스칼라는 자바의 1/4 수준의 언어 명세만으로 자바 이상의 표현능력을 갖추고, 훨씬 간결한 소스코드로 사람들을 유혹하고 있다. 자바는 스칼라가 제공하는 기능을 일부라도 흉내 내고자 수년째 절치부심이다.

책 전체적으로 자바의 위기와 그렇게 된 재미난 역사적 사실과 철학적인 이야기들, 그리고 자바의 미래를 당장 엿볼 수 있는 다른 언어의 특징이 일관되게 묘사되고 있다. 하지만 저자가 에필로그에서도 밝혔듯, 자바는 낡았으니 다른 언어로 갈아타라는 메시지를 던지고자 하는 것은 아니다.

임백준씨가 말끔히 정리해놓은 문장이 있지만, 내식대로 표현해보자면 이렇다.

자바 세계에서 잠시 눈을 돌리면 새로운 패러다임의, 혹은 훨씬 진보한 (그래서 자바도 흉내 내려 부단히 노력 중인) 언어가 많이 있다. 그러한 언어들을 함께 쓸 줄 아는 프로그래머는 더 생산적이고 유연하여 어떠한 환경에서건 쉽게 적응하고 살아남을 것이다.

개인적으로는 2005년 이후 자바로부터 떠나 지내던 약 5년 동안의 이야기를 많이 들을 수 있어서 즐거웠다.

‘메타프로그래밍’이란?
Feb 27th, 2014 by Wegra Lee

메타?

나중에 더해져서 다른 개념을 보강 혹은 완성하는 것
A concept which is an abstraction from another concept, used to complete or add to the latter.

메타 데이터?

다른 데이터를 기술하는 데이터

metadata

책이라는 ‘실체를 훼손하지 않고’ ‘언제건’ 정보를 ‘더하거나 수정’할 수 있다.
‘실체에 접근하지 않고도’ 메타 데이터만으로 대상을 다룰 수 있다.
예> 분류, 검색, 정렬 등

메타 프로그래밍?

프로그래밍에 메타 정보를 활용하는 것!
즉, 프로그램 본체 작성 후에 새로운 기능을 추가하거나 다른 용도로 사용할 수 있게 정보를 제공할 수 있다.

활용 예>

* 자바 어노테이션 (참고 – JUnit 4, 60초만에 익히기)
* AOP(Aspect-oriented programming): 로깅, 동기화, 권한 확인 등
* C++ 템플릿 메타프로그래밍
* Ruby: 런타임에 객체 인스턴스에 새로운 메서드 추가

장점

부차적인 요소 혹은 변경될 소지가 있는 요소를 메타 정보로 추출하여 핵심 로직만 남겨둘 수 있다.
따라서 소스 코드의 가속성과 프로그램의 유연성이 높아진다.

단점

자칫 전체 로직의 연결 고리 일부가 사라져서 프로그램을 이해하기 어렵게 만들 수 있다.

6. 피드백 컨트롤러 튜닝(Feedback Controller Tuning)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


앞의 글에서 피드백 루프에 사용할 PID 컨트롤러를 소개했다.

이를 수식으로 나타내면 다음과 같으며

janert-feedback-controller

비연속적 시간 형태로 바꿔 소프트웨어로 구현한 모습은 다음과 같다.

sum += error
output = kp * error + DT * ki * sum + kd * (error – prev) / DT
prev = error

컨트롤러 상수인 Kp, Ki, Kd는 컨트롤러를 운영 환경에 적응하기 위한 값이다. 캐시의 예에서 보면, 출력(제어하려는 지표)은 0.0 ~ 1.0 사이의 값이지만, 입력(컨트롤러가 계산해야 할 양)은 훨씬 큰 정수값이다. 이제 이러한 범위의 차에 적응할 수 있는 적절한 컨트롤러 상수를 선택해야 한다.

janert-feedback-loop2

자! 앞으로 입력과 출력이라는 용어는 항시 제어 입력과 제어 출력을 의미할 것이다. 즉 우리 관심사인 지표가 출력이고, 그 값에 움직이기 위해 우리가 조절할 수 있는 양은 입력이다. 이런 제어 입력이나 출력은 물론 캐시에 아이템을 넣고 빼는 요청과는 아무런 상관이 없는 개념이다.

우리는 다음 질문의 답을 찾아야 한다. 시스템의 출력에 원하는 만큼의 변화를 주려면 입력은 얼마나 변경해야 하는가? 캐시에서라면 ‘적중률을 0.1만큼 조정하려면 캐시 크기에 어느 정도의 변화를 줘야 할까?’ 정도의 질문이 될 것이다.

대게 가장 간단한 (아마도 가장 정확하기도 할) 답변은 직접 측정해보는 것이다. (피드백 루프 없이) 캐시를 잠시 운영해보고 크기를 바꾼 후 적중률이 안정되기를 기다란 다음 새로운 적중률을 이전 값과 비교해본다. 이렇게 구한 컨트롤러 상수의 첫 후보는 다음과 같다.

k = (size_after – size_before) / (hitrate_after – hitrate_before)

초기의 캐시 크기가 1,000에 적중률은 0.7이었고, 이를 1,200으로 키우니 적중률이 0.9까지 올랐다고 치자. 그 결과는 다음과 같다.

k = (1200 – 1000) / (0.9 – 0.7) = 200 / 0.2 = 1000

첫 시도 치곤 나름 괜찮다. 일반적으로 컨트롤로 상수가 클수록 변화에 민감하게 반응하지만, 안정성이 떨어져서 자칫 불안정한 상태로 빠질 가능성이 커진다. 결국, 절대적으로 옳은 값이 있는 것은 아니다. 대신 반응속도와 안정성을 적절히 조화시켜야 하는 문제라, 응용 분야가 달라지면 최적의 제어 전략도 바뀌게 된다.

적절한 컨트롤러 상수를 구하는 일(컨트롤러 튜닝)이 정말 중요하다. 잘못 선택한 상수는 만족스럽지 못한 동작을 낳는다. 변화에 너무 굼떠서 답답한 시스템이 되거나 너무 쉽게 요동치는 불안정한 시스템이 될 것이다. 컨트롤러 튜닝이 중요한 만큼 업계는 이 값을 구하는 다양한 기법을 개발해 왔다. 물론 완벽한 방법이란 존재하지 않는다. 최적의 상수는 시스템 자체뿐 아니라 우리가 그 시스템을 활용하는 방식에도 영향을 받기 때문이다.

튜닝 방식 중 하나는 앞서 논의한 방식과 유사하다. 시스템 입력을 한 단위만큼 변경하고 시스템의 출력을 관찰한다. 다른 점이라면 출력의 변화를 시간을 두고 관찰한다는 것이다. 그 결과는 다음 그림처럼 보일 것이다. 입력 한 단위의 변경에 따른 이처럼 동적인 반응을 ‘공정 반응 곡선(process reaction curve)’이라 한다.

janert-feedback-step

이 그래프는 정적인 입출력 관계뿐 아니라 시스템이 얼마나 빠르게 새로운 값으로 안정화되는가 하는 정보도 담고 있다. 시스템이 다시 안정되기까지의 이 시간을 공정의 “시간 상수(time constant)”라 하며, 컨트롤러 상수에 반드시 반영되어야 할 값이다. 기본적으로 느리게 반응하는 시스템일수록 더 강하게 조치해야 하며 이 곡선의 여러 속성으로부터 컨트롤러 상수를 구하는 다양한 휴리스틱을 개발해 왔다.

컨트롤러 튜닝은 피드백 루프가 올바로 작동하기 위한 핵심이다. 항상 최적값을 내어주는 절대 규칙도 없고, 방금 언급한 휴리스틱 역시 너무 다양하다. 이 모든 것은 어쩌면 예술, 아니 마법의 영역일 지도 모른다. 하지만 원리만 잘 이해한다면 이러한 어려움도 이겨낼 수 있다.

다음 글에서는 피드백의 기본 개념을 다시 상기하며 더 일반적인 개념인 “자가 적응(self-adaptive)” 시스템과 어떻게 다른지 논해보겠다.

5. 피드백 컨트롤러(Feedback Controllers)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


지금까지는 설계 원칙 혹은 패러다임 관점에서 피드백을 소개했다. 한 마디로, 피드백은 불규칙하게 변화하는 환경에서 시스템이 정상궤도를 유지하게끔 도와준다. 그럼 이번 글에서는 이것이 실제로 의미하는 것이 무엇인지 더 자세히 살펴보기로 하자.

janert-feedback-loop2

그림의 피드백 루프를 보자. 제어 대상 시스템은 이번에도 캐시다. 컨트롤러는 목표 캐시 적중률을 유지하기 위해 캐시의 크기를 조절한다. (캐시 크기를 키우면 적중 횟수가 많아지고 자연히 적중률이 높아질 것이다.) 목표 캐시 적중률은 참조값 혹은 설정값(setpoint)이라 부르며 그림 가장 좌측의 입력으로 쓰인다. 컨트롤러의 입력값인 추적 오차는 설정값과 실제 적중률의 차이다.

추적 오차 = 설정값 – 실제값

(측정한 적중률은 -1을 곱한 후 참조값에 더한다. 이 값이 바로 설정값과 측정된 값의 차이인 추적 오차다.)

컨트롤러는 추적 오차를 입력받아 새로운 캐시 크기를 산출한다. 이 과정은 정확히 어떻게 이루어질까? 추적 오차가 음수면(실제 적중률이 목표한 적중률보다 높음) 캐시 크기가 줄어야 함을 기억해두고 계속 진행해보자.

이때 가장 최근의 측정 결과가 중요하다. 그 순간의 추적 오차가 캐시의 현재 크기를 목표 수준으로 조정하는 데 쓰인다. 즉, 제어 알고리즘은 다음과 같이 요약할 수 있다.

새로운 크기 = 이전 크기 + k * 추적 오차

추적 오차가 음수면(실제 적중률이 목표치보다 높음) 캐시 크기는 줄어들 것이다. 반대로 추적 오차가 양수면(실제 적중률이 목표치보다 낮음) 캐시 크기는 줄어들 것이다.

상수 k는 증감의 민감도를 결정한다. 적중률의 범위는 0.0 ~ 1.0 사이기 때문에 추적 오차 역시 0.0 ~ 1.0 사이의 실수(floating point number)여야 한다. 반면 캐시의 크기는 정수이며, 요청 트래픽에 따라 매우 큰 값이 될 수도 있다. k는 이러한 차이와 무관하게 어떠한 환경에서도 피드백 루프를 튜닝할 수 있는 값이어야 한다. 환경이 바뀐다고 새로운 컨트롤러를 쓰고 싶어하는 사람은 없기 때문이다.

적절한 컨트롤러 k를 구하려면 잠시 제어 알고리즘의 구조를 살펴볼 필요가 있다. 이 알고리즘은 적중률이 너무 높거나 너무 낮아도 항시 유효해야 한다. 이 공식에 따르면 수정치는 추적 오차에 비례한다. 끝으로, 추적 오차가 사라지면(실제 적중률이 목표 적중률과 일치함) 캐시 크기는 변하지 않아야 한다.

이쯤되면 대다수의 피드백 컨트롤러가 위와 같은 간단한 공식을 사용한다는 사실은 전혀 놀랍지 않다. 하지만 다른 속성을 고려해야 할 때도 있다. 가장 널리 쓰이는 소위 “세 단어(three-term)” 컨트롤러 혹은 PID (”proportional, integral, derivative”) 컨트롤러의 출력을 좌우하는 속성은 다음과 같다.

  • 현재 오차(현재)
  • 지금까지의 모든 오차의 누적합(과거)
  • 가장 최근 오차의 변화량(예측된 미래)

수학적으로는 누적합(cumulative sum)은 적분(integral), 최근 변화는 미분(derivative)으로 표현된다. 즉, PID 컨트롤러의 출력 공식은 다음과 같다.

janert-feedback-controller

여기서 컨트롤러 상수인 Kp, Ki, Kd는 모두 숫자 값이고, e(t)는 현재 오차다. 미분의 경우 무시될 때도 잦다(즉, Kd = 0). 여기에 Kp = 0으로 정하면 앞의 한 줄짜리 간단한 공식과 같아진다.

이를 컴퓨터로 구현하려면 시간의 흐름이 비연속적인 값으로 바꿔야 한다(다음 공식의 DT). 따라서 PID 컨트롤러의 구현은 다음과 같다.

sum += error
output = Kp * error + DT * ki * sum + kd * (error – prev) / DT
prev = error

이제 됐다! 이것이 그 유명한 PID 컨트롤러다! 바로 업계 90% 이상에서 활용한는 대표 컨트롤러다.

피드백 제어는 복잡한 구조를 단순한 컨트롤러로 대체한다. 이것이 피드백 시스템의 핵심이다. 피드백 시스템이 잘 작동하는 이유는 단순히 컨트롤러가 영리해서가 아니라, 정보를 루프 앞단으로 돌려보내 컨트롤러의 입력으로 재사용(feed back)하기 때문이다.

이제 컨트롤러 상수(Kp, Ki, Kd)를 정하는 방법을 알아볼 차례다. 그럼 다음 포스팅을 기대하기 바란다.

4. 피드백은 다르다(Feedback is Different)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


이전 글에서 우리는 피드백이 일반적인 알고리즘 방식과는 다르다고 주장했다. 그럼 이제 어떻게 다른지 자세히 알아보자.

보통의 알고리즘은 결정적이고 가능한 모든 결과를 나열할 수 있다는 가정을 가지고 있다. 예를 들어 “배열의 중간 원소를 취해라. 피봇(pivot)보다 작거나 같으면 이것을 하고, 아니면 저것을 하라.”는 식이다. 이런 방식으로 만들어진 제어 시스템은 규칙 기반이거나 휴리스틱(heuristic)에 의존한다. 즉 “매일 아침 10시에 서버 15대를 늘리고, 오후 4시에 다시 줄여라.’처럼 말이다.

이러한 시스템은 컨트롤러가 고정되어 있고(결정적이고) 시스템의 정확한 상태를 반영하지 못한다는 두 가지 문제에 봉착하기 쉽다. 사실 이 둘의 원인은 한 가지다.

첫 번째 문제는 휴리스틱 상수에 의한 문제다. 솔직히 휴리스틱은 ‘임기응변’의 완곡한 표현일 뿐이다. 왜 하필 15대지? 16대는 안 되나? 10시인 이유는 뭐야? 10분 일찍 늘리면 더 낫지 않을까? 사실 조금 바꿔도 상관없거나 오히려 더 잘 맞을 수도 있다. 비즈니스가 커가고 변화하며 이런 고정된 값은 심각한 레거시 문제가 되기도 한다.

시간이 지날수록 그 규칙이 점점 복잡해진다는 문제도 있다. 평상시에는 새로운 서버 15대만으로 충분하다가도 크리스마스 시즌이 되면 35대쯤이 필요할 수 있다. 누군가 주말에는 서버가 그다지 많이 필요하지 않다는 사실을 발견할 수도 있다. 그리고 주중엔 8시 30분부터 주문이 늘기 시작하니 8시 30분에 5대, 9시에 다시 5대, 10시에 나머지 5대를 차례로 늘리는 것이 최적일 수 있다.

근본적인 문제는 바로 “현실”은 전통적인 데이터 구조보다 훨씬 복잡하고 예측하기 어렵다는 점이다. 그러니 언제 어떻게 하라고 기술하는 피드포워드(feedforward) 방식은 실패하기 쉽다. 강건한 시스템이 되려면 시스템의 실 상태를 반영하여 적절히 대응해야 한다.

이것이 바로 피드백 루프가 하는 일이다. 서비스 품질 지표를 상시 관찰하여, 원하는 행동과 차이를 보이면, 원하는 방향으로 되돌리게끔 시스템에 수정을 가한다. 이 방식은 모든 것을 단 하나의 행위로 요약하기 때문에 룰엔진(rule-engine)을 극히 단순하게 만든다. “응답 시간이 길어지면, 서버 수를 늘려라. 그리고 역으로…” 문제의 휴리스틱 상수를 완전히 배제하고 낮이건 밤이건 주말이건 상관없이 모든 상황에 적용된다. 컨트롤러는 언제건 시스템을 빠릿하게 유지해줄 것이다.

이러한 시스템을 설계하려면 사고의 전환이 필요하다. 어떤 경우에 어떠한 조치를 해야 하는지 명확하기 기술하려는 생각은 완전히 버려야 한다. 대신 시스템의 동작을 고민하고 시스템을 원하는 방향으로 몰고 가기 위해 취해야 할 적절한 변화(조작)가 무엇인지 설계해야 한다.

또한, 피드백 제어는 운전대를 조종하는 손의 움직임처럼 미묘해서 이런 시스템은 굉장히 신경 써서 설계해야 한다. 실제도 (마치 마법처럼) 동작하는 모습을 보기 전까지는 명시적인 제어를 완전히 포기하기란 절대 쉽지 않을 것이다.

끝으로, 지식과 기술이 뒷받침되어야 이런 시스템을 구축할 수 있다. 섣불리 시도했다가는 실패의 쓴맛과 함께 룰엔진에 계속해서 새로운 예외를 더해줘야 하는 악마의 방법에 머무르게 될 것이다. 가장 중요한 도전은 환경 변화에 충분히 빠르게 반응하면서 동시에 너무 지나쳐서 오히려 비정상적인 상황이 발생하지 않도록 균형을 잡는 일이다. 즉, 웹 트래픽이 증가할 때 재깍 서버의 수를 늘려 반응 속도가 느려지지 않게 해야 함과 동시에 필요 이상으로 많이 늘려서도 안 된다.

컨트롤러 튜닝을 이야기하기에 앞서, 전형적인 피드백 컨트롤러의 모습부터 이해해 두는 것이 좋을 것이다. 그럼 이 주제로 곧 찾아뵙도록 하겠다.

»  Substance: WordPress   »  Style: Ahren Ahimsa