[현장] 전설의 개발자 제프 딘, 한국 개발자를 만나다

최근 알파고와 이세돌 9단의 대국에 많은 관심이 쏠리고 있습니다. 데미스 하사비스 구글 딥마인드 최고경영자부터 에릭 슈미트 알파벳 회장까지 한국에 방문해 인간과 인공지능과의 대결에 관심을 보이고 있는데요. 지난 월요일 알파고 인기 못지 않게 유명한 구글 직원이 한국에 방문했습니다. 바로 제프 딘이라는 구글 시니어 펠로우입니다.

제프 딘은 일반인에게는 조금 생소하지만 IT 업계에서는 널리 알려진 ‘전설’같은 인물입니다. 제프 딘은 1999년 중반 구글에 합류했는데요. 구글의 대부분의 제품의 기본이 되는 구글의 크롤링, 인덱싱 및 쿼리 서빙 시스템을 비롯해 구글의 주요 초기 광고 모델과 애드센스 시스템을 공동 설계하고 구현하는 데 기여한 인물입니다. 뿐만 아니라 ‘스패너’, ‘빅테이블’, ‘맵리듀스’ 등을 개발한 엔지니어로 현재는 머신러닝을 위한 대용량 분산 시스템에 대해 연구하고 있습니다.

제프 딘은 3월7일 구글 캠퍼스에서 머신러닝에 대한 강연을 하고 한국 엔지니어들과 1시간 가량 직접 소통하는 시간을 가졌습니다. 이날 행사에는 500명이 넘는 한국 개발자가 등록 신청서를 제출했다고 합니다. 구글코리아는 사전 신청서와 질문 내용을 확인하고 200여명의 개발자만 추려 현장에 참석할 수 있는 기회를 제공했습니다. 강의는 2시부터 시작했지만, 이미 1시30분터 구글캠퍼스 강연장에는 사람이 꽉 찼습니다.  2시가 되자 발 디딜 틈이 없었습니다. 실제 참여자는 210명이 넘었다고 하네요.

jeff_dean_01

▲행사는 사전 등록해서 뽑힌 사람만 참여할 수 있었습니다

jeff_dean_02

▲행사는 사전 등록해서 뽑힌 사람만 참여할 수 있었습니다

이날 행사는 유튜브에 생중계되기도 했는데요. 영상은 현재 무료로 공개됐습니다. 2시 정각 드디어 제프 딘이 등장했습니다. 여기저기서 휴대폰을 들고 사진을 찍는 모습을 볼 수 있었습니다. 마치 연예인을 본 것처럼 말이죠. 제프 딘은 ‘텐서플로’의 로고가 들어간 티셔츠를 입고 등장해 눈길을 끌었습니다. 텐서플로는 최근 구글이 공개한 오픈소스 머신러닝 기술이죠.

jeff_dean_03

▲제프 딘 구글 개발자를 소개하는 권순선 구글 APAC 개발자 플랫폼 총괄

jeff_dean_04

▲제프 딘 구글 시니어 펠로우

이날 발표 주제는 크게 2가지였습니다. 딥 뉴런 러닝이 무엇인지 이야기하고, 텐서플로를 소개했죠. 머신러닝에 대한 간략한 개론을 알고 싶은 분이라면 이번 강의가 도움이 되실 겁니다.

제프 딘 발표 영상 다시보기

현장에서 따로 통역이 지원되지 않았습니다. 현재 공개된 유튜브 영상에서도 자막이 지원되지는 않습니다. 1시간 가량 강연이 끝나고 3시부터는 약 30분간 질의응답 시간을 가졌는데요. 사전 질문을 미리 받아 답변하고, 나머지는 즉석에서 질문과 답변을 주고받았습니다. 현장에서 질문하려는 사람은 굉장히 많았는데요. 한 번에 10여명의 참가자가 동시에 손을 드는 풍경이 이어졌습니다. 참가자들 상당수는 이 질의응답 시간에서 좋은 정보들을 받았다고 후기를 남겼습니다. 제프 딘은 강연이 끝난뒤 추가 질문이 있는 10여명의 개발자들과 일일이 대화를 이어갔습니다.

jeff_dean_00

다음과 제프딘과 한국 개발자들 사이에서 진행된 일부 질의응답 내용입니다.

질문 : 인공지능과 사람의 지능과의 가장 큰 차이점은 무엇인가 ?

답변 : 인간의 지능이 인공지능보다 더 나은 점은 현상을 관찰하고 세상을 이해하는 능력이다. 인간은 다양한 상황을 관찰을 통해 이해한다. 예를 들어, 사람은 한번도 보지 못한 물건을 집어도 무엇을 해야 할지 이전의 경험과 정보를 기반으로 행동할 수 있다. 높은 수준의 언어를 이해하는 것도 비슷한 맥락이다. 컴퓨터는 이러한 능력이 부족하다. 하지만 우리는 열심히 이러한 문제를 해결하고 있는 중이다.

질문 : 알파고와 이세돌 9단의 대결에서 누가 이길 것 같은가?

답변 : 모두가 이번 대국에 관심이 많은 것 같다. 잘 모르겠다. 알파고는 지난번 유럽 챔피언 바둑 기사를 이겼다. 그 후 5개월 동안 알파고도 많이 배웠을 것이다. 알파고는 경험을 통해 배우지 않나. 승패의 핵심은 5개월 동안 알파고가 충분히 배웠는가인데, 잘 모르겠다.(웃음)

질문 : 현재 ‘CTNK’나 ‘카페’ 등 머신러닝와 관련된 오픈소스 라이브러리가 많다. 이와 비교했을 때 텐서플로만의 장점은 무엇인가?

답변 : 현재 다른 종류의 오픈소스 머신러닝 기술이 있고, 서로 다른 특징을 가지고 있다. 구글도 다른 머신러닝 기술의 장점을 가져오려고 많이 노력하고 있다. 예를 들어 자동화를 어떻게 할 것인지 등을 고민했다. 텐서플로의 장점은 유연하다는 것이다. 연구 영역에서는 더욱 그렇다. 또한 연구환경 뿐만 아니라 기업에서 실제 기술에 배포해서 쓸 수 있도록 다양한 지원을 해주고 있다. 데이터센터나 모바일 앱에 적용할 수 있다. 실제로 구글은 안드로이드 앱에 텐서플로를 적용해 활용하고 있다.

질문 : 당신과 같이 좋은 개발자가 되려면 매일 무엇을 해야 할까?

답변 : 아침을 먹어라. (웃음) 내가 좋아하는 것은 내가 알지 못하는 다른 분야 전문가와 만나고 이야기하는 것이다. 다른 전문가와 함께 이야기 하면 혼자 내놓을 수 있는 결과보다 훨씬 다른 결과를 만들 수 있다. 다른 사람의 전문분야에서 무엇인가를 배울 수 있다고 본다. 그러한 경험이 다음에 무엇인가 시작할 때 도움을 받을 수 있다.

질문 : 작은 회사에서는 양질의 데이터를 대량으로 얻기 힘들다. 대학에서도 그렇다. 많은 컴퓨팅 자원을 활용하기도 힘들다. 작은 회사나 그룹에서 머신러닝을 어떻게 연구해야 하는지 조언해 줄 수 있나?

답변 : 큰 회사는 많은 데이터를 접근할 수 있다는 장점을 가진다. 작은 회사라면 외부에 공개된 데이터들도 일단 풀고 싶은 문제를 해결하기 위해 모델을 만들 수 있을 것이다. 똑같지는 않지만 비슷한 모델을 만들 수 있다. 그리고 조금씩 뜯어고치면서 더 나은 훈련을 할 수 있을 거라고 본다. 구글이 향후 새로운 데이터를 공개할 것인지는 여기서 언급할 수 없다. ‘이미지넷’ 데이터는 이미 외부에 공개했다. 이 데이터는 컴퓨터 비전 분야에 영향을 주었다. 컴퓨팅 자원 문제는 클라우드를 이용하면서 해결할 수 있을 거라고 본다.

질문 : 엔지니어로 살아오면서 저질렀던 가장 큰 실수는 무엇인가? 또 그 실수는 어떻게 해결했는가?

답변 : 아주 많다. ‘빅테이블’이라고 있다. 2004-2005년께 만든 시스템이다. 그 시스템에는 분산 트랜잭션(distributed transaction)과 관련된 도구가 없다. 많은 팀이 그 기능을 원했다. 이 기능이 없어서 제대로 동작 안 되는 부분이 있었다. 그래서 빅테이블 핵심 기술 안에 분산 트랜잭션 기능이 있었어야 하는거 아닌가라는 생각이 들었다. 향후 ‘스패너’를 만들어 보안하기도 했다.

질문 : 만약에 게임을 스스로 할 수 있는 AI를 만든다고 치자. 그 AI를 만드는 개발자는 해당 게임을 아주 전문적으로 잘 해야 하는가? 비슷한 질문으로, 알파고 연구자들은 바둑을 잘 두는가?

답변 : 질문을 조금 확장해서 이야기하자면, 당신이 만약에 특정 문제를 머신러닝으로 풀려고 한다면, 당신은 해당 문제와 관련한 분야에 전문성이 있어야 한다. 또한 관련 전문가가 함께 일한다면 도움을 받을 수 있다. 하지만 전문가가 없는 경우가 대부분이다. 예를 들어, 의학 이미지를 연구한다고 했을 때 엑스레이 사진을 해석할 수 있는 전문가가 옆에 있으면 좋을 것이다. 그렇다고 모두가 엑스레이 전문가가 될 필요는 없다. 알파고 연구원들 중에는 바둑을 둘 수 있는 사람이 몇 명 있는 걸로 알고 있다. 또한 바둑을 잘 모르는 연구원도 있다.

질문 : 당신은 그동안 많은 문제를 해결했다. 문제 해결을 보통 어떻게 하는가? 구글 검색도 하는가? 아니면 동료에게 물어보는가?

답변 : 둘 다 맞는것 같다. 검색엔진은 유용하지 않나. (웃음) 나도 검색을 한다. 동료와 토론하는 것도 아주 유용하다. 동료와 토론할 수 있는 문화는 구글 환경에서 좋아하는 부분이다. 구글에는 서로 배경이 다른 다양한 사람이 있다. 가끔씩 아주 놀라울 정도로 넓고 다양한 지식을 가진 사람이 있다. 그런 사람들에게 질문을 하고 배우기도 한다.

질문 : 딥러닝은 현재 음성, 비디오, 언어 분야에 적용돼 활용되고 있다. 앞으로 구글은 어떤 애플리케이션에 딥러닝을 적용할 예정인가? 딥러닝의 수준을 어떻게 평가하는가?

답변: 로봇이나 헬스케어쪽에 딥러닝이 더 적용되지 않을까 싶다. 머신러닝을 적용하기에 유용한 분야다. 딥러닝의 수준을 파악할 때 필요한것은 기계가 이전에 풀어본적 있는 비슷한 문제를 다시 풀 수 있느냐다. 새로운 데이터를 적용해서 풀 수 있는지도 중요하다.

질문 : ‘제프 딘의 29가지 진실‘에서 진짜 내용은 얼마나 있는가?

답변 : 제프딘의 진실은 사실 동료가 만우절 장난으로 만든거다. 그게 여기저기 퍼졌다. 굉장히 나를 칭찬하는 것처럼 이야기했는데, 조금 민망하다. (웃음)

질문 : 가장 좋아하는 언어는 무엇인가?

답변 : 나는 C++와 애증 관계에 있다. (웃음) C++는 아주 유용하지만 동시에 최근 몇 년간 복잡해졌다. C++11, C++14가 나오지 않았나. 새로운 기능이 나오기도 했다. 보통 C++로 작업한다. 하지만 구글 동료들이 만든 ‘고’ 언어에 대해서도 관심이 많다. 실제로 고로 프로그래밍을 해본 적은 별로 없다. 하지만 고는 간단하고 로우 레벨 시스템을 개발하는 데 도움이 된다고 본다.

질문 : 텐서플로 티셔츠는 어떻게 얻을 수 있는가?

답변 : 오늘은 하나밖에 안 가져왔다. (웃음)

3월7일 행사 참가자 중 상당수는 향후 업무에 딥러닝을 적용할 계획을 가지고 있었습니다. 머신러닝 연구 때 사용할 수 있는 데이터에 대해 관심을 보이기도 했습니다. 고등학생, 대학생, 게임회사 개발자, 스타트업 CEO 등 다양한 출신의 개발자를 볼 수 있었습니다. 이들의 소감을 들어볼까요.

올해 18살인 이승우 학생은 “머신러닝 스터디 모임에 참여하면서 제프 딘 행사도 있다는 것을 알고 오고 싶었다”라며 “한국에도 데이터세트가 API를 통해서라도 개방돼 머신러닝 연구원들에게 많은 길이 열렸으면 좋지 않을까 생각했다”라고 밝혔습니다. 딥러닝 전문 기업을 운영하는 김선우 딥바이오 CEO는 “제프 딘은 최근에 딥러닝 분야에서 여러 발표를 하던 분이라 딥러닝 공부하는 사람으로서 그 존재를 이미 알고 있었다”라며 “데이터가 많아질수록 큰 규모의 모델과 더 많은 계산이 필요하고 이로 인해 좋은 결과를 낼 수 있다는 말이 인상적이었다”라고 소회를 밝혔습니다.

외국인이자 텀블벅에서 일하고 있는 비욘 개발자는 “제프 딘은 가장 뛰어난 컴퓨터과학자 중 한명으로 널리 알려져 있다”라며 “텐서플로우에 대한 소개와 딥러닝을 구글에서 어떻게 활용하는지 이야기하는 부분이 기억난다”라고 말하더군요. 또한 차창호 프리랜스 개발자는 “AI 엔지니어는 아니지만 최근 트렌드가 되니깐 계속 관련 논문이나 글을 찾아보고 있다”라며 “이번 발표는 아주 새로운 이야기를 하는건 아니지만 제프 딘을 통해 직접 설명을 들을 수 있다는 점이 의미가 있었다”라고 말했습니다. 서재원 서강대 대학생은 “제프 딘은 텐서플로우를 만든 사람으로 알고 있다”라며 “실제 발표를 듣고 만나니 상당히 대단한 분이라고 생각이 들더라”라고 말했고요. 길소연 대학원생은 “향후 업무에서 머신러닝을 도입할 예정”이라며 “작은 회사에서 데이터들을 어떻게 얻고 활용해야 하는지, 또 학생으로서 딥러닝 공부는 어떻게 해야되는지 대한 답을 얻을 수 있었다”라고 소감을 밝혔습니다.

이번 행사를 총괄한 권순선 구글 APAC 개발자 플랫폼 총괄은 “오늘 이렇게나 많은 질문이 나올지 몰랐다”라며 “참여 개발자들의 열정과 관심에 놀랐다”라고 행사에 만족감을 표시했습니다.

출처: https://www.bloter.net/archives/251561


'Others' 카테고리의 다른 글

OOP - S.O.L.I.D  (0) 2016.03.22
Bluetooth Low Energy  (0) 2016.01.26
코드 하이라이트 사용법  (0) 2015.10.26
  • Exception
    package kr.co.ioacademy;
    // 자바의 예외 3가지
    // 1. 점검 지정 예외     : 복구가 가능한 상황
    // 2. 무점검 지정 예외    : 복구가 불가능한 상황
    //  1) 실행 시점 예외(Runtime Exception) - 사용자
    //  2) 오류(Error) - JVM
    
    // API 사용자에게 점검 지정 예외를 준다는 것은 그 상태를 복구할 권한을 준다는 것이다.
    // (무시할 수 있지만 무시하면 안된다)
    
    // 실행 시점 예외와 오류의 동작 방식은 동일하다.
    // -> 둘다 catch 할 필요가 없다. 처리해서도 안된다.
    
    
    class Engine {}
    
    class Car {
    
      private static Class<Engine> engineClass = Engine.class;
    //  private Engine engine = engineClass.newInstance();
    //  // 2. 인스턴스 필드의 초기화에서 발생하는 예외는 생성자에서 처리해야 한다.
    //  public Car() throws Exception {
    //  }
    
      private Engine engine = newEngine();
      private static Engine newEngine() {
        try {
          return engineClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
          e.printStackTrace();
        }
        return null;
      }
    
      /*
      // 1. 인스턴스 필드가 생성자 호출보다 먼저 일어난다.
      private Car instance = new Car();
      public Car() throws Exception {
        throw new Exception("Failed to create");
      }
      */
    }
    
    public class Example9 {
      public static void main(String[] args) {
        try {
          Car car = new Car();
          System.out.println("Succeed");
        } catch (Exception e) {
          System.out.println("Failed");
        }
      }
    }

  • Assertion
    : jdk 1.4부터 도입
    : Assertion은 불리언 식(expression)을 포함하고 있는 문장으로서, 프로그래머는 그 문장이 실행될 경우 불리언 식이 참이라고 단언할 수 있다. (JSR, Java Specification Request) 
    : Assertion은 개발자가 참이라고 가정하는 상태를 명시하기 위해서 사용된다. (예를 들어, 어떤 메소드가 파라미터로 양수만 입력받아야 한다고 확신한다면, Assertion을 사용하여 그 사실을(즉, 파라미터가 양수라는 것을) 명시할 수 있다.)

    // jdk 1.4
    // javac -source 1.4 AssertionTest.java 
    // JRE 클래스가 Assertion을 포함하는지 여부에 상관없이 기본적으로 Assertion 기능을 사용하지 않는다.
    // java -ea AssertionTest
    
    
    // 문법
    // assert [boolean 식];
    // assert [boolean 식]:[표현식];
    
    // 사용해선 안 되는 경우
    // public 메소드의 파라미터를 검사하는 경우
    // 올바른 수행을 위해 필요한 작업을 수행하는 경우
    // ex) assert checkName(); -> boolean checked = checkName();
    // 							  assert checked;
    
    public class AssertionTest {
    	// Assert 기능 강제적으로 사용하도록 유도
    	static { 
    		boolean assertsEnabled = false;
    		assert assertsEnabled = true;        if (!assertsEnabled)
    			throw new RuntimeException("Assertion 기능이 사용가능해야 합니다!");
    	}    
    
    	/*    
        // post-condition check
    	Object getObj(Object obj) {
    		assert obj != null : "obj cannot be null";
    
    		return obj;
    	}
     
        // pre-condition check
    	void register(MemberInfo member) {
    		assert Member != null:"MemberInfo cannot be null";
    		assert member.getId() != null && !member.getId().equals("");
    
    	        ...
    	}
    	 */
    
    	public static void main(String[] args) {
    		char operator = '%';                  // assumed either '+', '-', '*', '/' only
    		int operand1 = 5, operand2 = 6, result = 0;
    		switch (operator) {
    			case '+': result = operand1 + operand2; break;
    			case '-': result = operand1 - operand2; break;
    			case '*': result = operand1 * operand2; break;
    			case '/': result = operand1 / operand2; break;
    			default: assert false : "Unknown operator: " + operator;  // not plausible here
    		}
    		System.out.println(operand1 + " " + operator + " " + operand2 + " = " + result);
    	}
    }
    
    참고 : http://javacan.tistory.com/entry/79, https://www3.ntu.edu.sg/home/ehchua/programming/java/J5a_ExceptionAssert.html


'Programing > Java' 카테고리의 다른 글

Effective Java - Annotation  (0) 2016.03.08
Effective Java - Reflection  (0) 2016.03.08
Effective Java - 스레드(2)  (0) 2016.03.07
Effective Java - 스레드(1)  (0) 2016.03.07
Effective Java - 불변 객체  (0) 2016.03.07
  • Anotation
    - Java Annotation?
     : 어노테이션은 어노테이션된 요소들의 행동으로부터 프로그램의 행위를 추출하여, 필요하다면 컴파일러나 VM이 상호 의존적인 코드를 생성하는, 프로그램 요소와 메타 태그에 관계된 매커니즘.
     : 사전적으로는 "주석"이라는 의미를 가지고 있으며, 의미대로 자바 코드에 주석처럼 달아 특수한 의미를 부여해준다. 이 특별한 의미는 컴파일 타임 또는 런타임에 해석 될 수 있다.


    - .java부터 .class까지

  •  : .java => Parser => Type checker => [Annotation Checker] => Class File writer => .class


    - 어노테이션 규칙

     : @interface + 어노테이션 이름

     : 어노테이션 소스코드 내부의 메소드 선언은 매개변수를 지닐 수 없다.

     : 어노테이션 소스코드 내부의 메소드 선언은 clauses를 throw 할 수 없다.

     : 메소드의 반환 타입은 primitives, String, Class, enum과 primitives배열, String배열, Class배열, enum배열 중 하나이다.


    - 분류

     1. marker ; @AnnotationTypeName
      : 멤버 변수가 없으며, 단순히 표식으로서 사용되는 어노테이션이다. 컴파일러에게 어떤 의미를 전달한다.

     2. single-element ; @AnnotationTypeName(single-element)
      : 멤버로 단일변수만을 갖는 어노테이션이다. 단일변수 밖에 없기 때문에 (값)만을 명시하여 데이터를 전달할 수 있다.

     3. normal, full-value, multi-value ; @AnnotationName(element=value, element=value, ...)
      : 멤버로 둘 이상의 변수를 갖는 어노테이션으로, 데이터를 (값=쌍)의 형태로 전달한다.


    Built-in Annotation

    == java.lang.annotation (meta-annotation)

    @Retention

     : Retention은 어노테이션이 얼마나 오랫동안 유지되는지에 대해, JVM이 어떻게 사용자 어노테이션을 다루어야 하는지를 서술합니다.

     * SOURCE - 어노테이션이 컴파일 타임시 버려진다는 것을 의미합니다. retention정책이 source로 정의되어 있으면, 클래스 파일은 어노테이션을 지니지 못합니다.

     * CLASS - 어노테이션이 생성된 클래스 파일에서 나타날 것이라는 것을 의미합니다. 그러나 런타임시에는 이 어노테이션을 이용하지 못합니다.

     * RUNTIME- 이는 런타임시 JVM에서 어노테이션의 이용이 가능하다는 것을 의미합니다. 이러한 어노테이션을 읽는 사용자 로직을 가짐으로써 런타임시 무언가를 할 수 있습니다.


    @Target

     : Target은 어디에 어노테이션을 넣을 수 있는지를 서술합니다. field, method, class가 정의된 곳에 어노테이션을 넣을 수 있습니다.

     * TYPE - class, interface, enumeration에 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * METHOD - method 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * PARAMETER - parameter 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * PACKAGE - package 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * FIELD - field 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * LOCAL_VARIABLE - 지역 변수 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * CONSTRUCTOR - 생성자에만 어노테이션을 적용할 수 있다는 것을 의미합니다.

     * ANNOTATION_TYPE - 어노테이션 타입에만 어노테이션을 적용할 수 있다는 것을 의미합니다.


    @Inherited

     - 기본적으로 어노테이션은 상속되지 않습니다. 따라서 상속을 원한다면, 어노테이션을 Inherited 해야 합니다. Inherited 어노테이션이 사용자 어노테이션에 놓여야 하며, 이는 클래스에만 효과가 있습니다. (즉, 상속받는 클래스도 같은 어노테이션 사용)


    @Documented

     - 어노테이션이 기본으로 javadoc 및 유사한 툴에 의해 문서화 되는 것을 나타냅니다. 이러한 형태는 타입의 선언에 주석을 달기 위해 사용합니다. 어노테이션은 클라이언트에 의해 어노테이션된 요소의 사용에 영향을 미치게 됩니다. 타입의 선언에 Documented 어노테이션을 붙인 경우, 그 어노테이션은 어노테이션된 요소의 공개 API중 한 부분이 됩니다.


    == java.lang

    @Override
     : 현재 메소드가 수퍼클래스의 메소드를 오버라이드한 메소드임을 컴파일러에게 명시한다. 만일 수퍼 클래스에 해당하는 메소드가 없으면 컴파일러가 인지하고 에러를 발생시켜 준다.

    @Deprecated
     : 마커 오노테이션으로 차후 버전에 지원되지 않을 수 있기 때문에 더 이상 사용되지 말아야할 메소드를 나타낸다. 특이하게 더이상 사용되지 말아야할 메소드와 같은 라인상에 놓여져야 한다.

    @SuppressWarnings
     : 의미대로 경고를 제거하는 어노테이션이다. Object형을 엘리먼트로 하는 컬렉션을 사용하면, 컴파일러 경고가 발생하는데 이 어노테이션을 사용하여 프로그래머의 의도적인 Object형 사용임을 알려 경고를 제거할 수 있다.

    출처: http://www-01.ibm.com/support/knowledgecenter/SSQ2R2_9.1.0/org.eclipse.jdt.doc.user/tasks/task-suppress_warnings.htm?lang=ko
    Java 5.0부터 java.lang.SuppressWarning 어노테이션을 사용하여 컴파일 단위의 서브세트와 관련된 컴파일 경고를 사용하지 않도록 설정할 수 있습니다.

    @SuppressWarning("unused") public void foo() { String s; }

    어노테이션이 없으면 컴파일러에서 로컬 변수 s를 사용할 수 없습니다. 어노테이션을 사용하여 컴파일러는 이 경고를 foo 메소드에 대해 로컬에서 무시합니다. 이러한 경우 동일한 컴파일 단위 또는 동일한 프로젝트의 다른 위치에 경고를 보관할 수 있습니다.

    SuppressWarnings 어노테이션 내부에서 사용할 수 있는 토큰 목록은 다음과 같습니다.

    • all 모든 경고를 억제합니다.
    • boxing boxing/unboxing 오퍼레이션과 관련된 경고를 억제합니다.
    • cast 캐스트 오퍼레이션과 관련된 경고를 억제합니다.
    • dep-ann 권장되지 않는 어노테이션과 관련된 경고를 억제합니다.
    • deprecation 권장되지 않는 기능과 관련된 경고를 억제합니다.
    • fallthrough switch 문에서 누락된 break 문과 관련된 경고를 억제합니다.
    • finally 리턴되지 않는 마지막 블록과 관련된 경고를 억제합니다.
    • hiding 변수를 숨기는 로컬과 관련된 경고를 억제합니다.
    • incomplete-switch switch 문에서 누락된 항목과 관련된 경고를 억제합니다(enum case).
    • javadoc javadoc 경고와 관련된 경고를 억제합니다.
    • nls 비nls 문자열 리터럴과 관련된 경고를 억제합니다.
    • null 널(null) 분석과 관련된 경고를 억제합니다.
    • rawtypes 원시 유형 사용법과 관련된 경고를 억제합니다.
    • resource 닫기 가능 유형의 자원 사용에 관련된 경고 억제
    • restriction 올바르지 않거나 금지된 참조 사용법과 관련된 경고를 억제합니다.
    • serial 직렬화 가능 클래스에 대한 누락된 serialVersionUID 필드와 관련된 경고를 억제합니다.
    • static-access 잘못된 정적 액세스와 관련된 경고를 억제합니다.
    • static-method static으로 선언될 수 있는 메소드와 관련된 경고를 억제합니다.
    • super 수퍼 호출을 사용하지 않는 메소드 겹쳐쓰기와 관련된 경고를 억제합니다.
    • synthetic-access 내부 클래스로부터의 최적화되지 않은 액세스와 관련된 경고를 억제합니다.
    • sync-override 동기화된 메소드를 오버라이드하는 경우 누락된 동기화로 인한 경고 억제
    • unchecked 미확인 오퍼레이션과 관련된 경고를 억제합니다.
    • unqualified-field-access 규정되지 않은 필드 액세스와 관련된 경고를 억제합니다.
    • unused 사용하지 않은 코드 및 불필요한 코드와 관련된 경고를 억제합니다.

    참고: http://netpyoung.tistory.com/100, http://hiddenviewer.tistory.com/88, https://en.wikibooks.org/wiki/Java_Programming/Annotations/Meta-Annotations

    - Custom Annotation

     : 클래스와 같이 어노테이션을 임의로 정의하여 사용할 수 있다. 어노테이션은 interface 키워드 앞에 @를 붙여 표시한다.
     : @interface InProgress{}

    - 예제

    package kr.co.ioacademy; // ioacademy 윤찬식 강사님
    // Simple JUnit4
    // 어노테이션(Annotation) ; 주석
    // Comment : 비공식적이고 임시적이다.
    // 정의 : 자바의 각 요소(클래스, 메소드, 필드, 매개변수) 가 가질 수 있는
    //        주석 리소스
    
    // 목적
    // 1. 컴파일러에게 추가적인 정보 전달
    // 2. 컴파일 할 때와 설치시의 작업 지정
    // 3. 실행할 때 별도의 처리를 수행
    
    // 기본 어노테이션
    // 1. @Override
    // 2. @Deprecated
    // 3. @SuppressWarnings
    
    // 1. 어노테이션을 만드는 방법.
    
    import java.lang.annotation.*;
    import java.lang.reflect.Method;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Test {
      boolean enabled() default true;
    }
    
    public class Example7 {
      @Test
      public void testA() {
        System.out.println("testA : do something");
      }
    
      @Test(enabled = true)
      public void testB() {
        System.out.println("testB : do something");
        throw new RuntimeException("failed to run");
      }
    
      @Test(enabled = true)
      public void testC() {
        System.out.println("testC : do something");
      }
    
      public static void main(String[] args) {
        System.out.println("Testing....");
    
        int count = 0;
        int passed = 0;
        int failed = 0;
        int ignore = 0;
    
        Class obj = Example7.class;
        for (Method method : obj.getDeclaredMethods()) {
    
          if (method.isAnnotationPresent(Test.class)) {
            ++count;
            Annotation annotation = method.getAnnotation(Test.class);
            Test test = (Test) annotation;
    
            if (test.enabled()) {
              try {
                method.invoke(obj.newInstance());
                ++passed;
                System.out.printf("Test '%s' - passed\n", method.getName());
              } catch (Throwable e) {
                ++failed;
                System.out.printf("Test '%s' - failed : %s\n", method.getName(),
                    e.getCause());
              }
            } else {
              ++ignore;
              System.out.printf("Test '%s' ignored\n", method.getName());
            }
          }
        } // for
    
        System.out.printf("Result - Total:%d, Passed:%d, Failed:%d, Ignore:%d\n",
            count, passed, failed, ignore);
      }
    
    }
    




'Programing > Java' 카테고리의 다른 글

Effective Java - Exception  (0) 2016.03.09
Effective Java - Reflection  (0) 2016.03.08
Effective Java - 스레드(2)  (0) 2016.03.07
Effective Java - 스레드(1)  (0) 2016.03.07
Effective Java - 불변 객체  (0) 2016.03.07

+ Recent posts