1. 소개

  • 작은 자바를 건드리면 어떻게 될까?
  • 2012년형 중장기 Java 스터디!

1.1. 누가?

  • 튜터: 변형진
  • 튜티: 김태진, 김준석, 권순의, 서민관, 서영주, 권영기
    • 누구나 참여 가능합니다. 각자 이름을 써주세요.
    • 최소 Java 기초 문법 이해 및 학부 2학년 1학기 커리큘럼 수준의 전산지식 필요
      • 이론과 실무 지식을 모두 다룰 예정이므로 Java 경험이 많을 수록 좋습니다.
    • 우앙 재밌겠다 - 서지혜
    • 흥미로워서 참여하고 싶지만 아직 서울에 갈만한 형편이 안되네요.. 흥미로운 주제를 다루시는것 같던데. - 안혁준

1.2. 언제?

  • 토요일 오후 1시부터

1.3. 어디서?

  • 제2공학과 6층 ZeroPage학회실 또는 컴퓨터공학부실습실

1.4. 무엇을?

  • 학교에서 배울 수 없는 Java에 대한 좀더 깊고 다양한 이야기
  • 다룰 법한 주제
    • Java Technology와 생태계
    • Java 개발 환경 및 빌드 프로세스
    • Java 프로그래밍 언어
    • Java API와 주요 기술
    • Java 개발 방법론
      • 객체지향 프로그래밍
        • 리팩터링
        • 디자인 패턴
      • 테스트 주도 개발
        • 유닛 테스트
        • Mock 프레임워크
    • Android 플랫폼
    • 등등…

1.5. 어떻게?

1.6. 왜?

  • 작은 자바의 작은 배때지에 칼빵을 놔주기 위해…?

1.6.1. 변형진

  • 현업 Java 개발자도 놓치기 쉬운 문제들을 짚어보고, 올바른 Java 프로그램을 빠르고 깔끔하게 구현하는데 필요한 중급 수준의 지식을 전달하기 위해
  • Java를 중점적으로 다루지만, Java에 한정되지 않은 폭넓은 컴퓨터공학적 이해를 바탕으로 사고하도록 하기 위해
  • 그동안 설계와 구현에 관한 일반론을 위주로 세미나를 진행해왔기에, 이번에는 좀더 practical하고 pragmatic한 지식을 전달하는데 비중을 두고자 함.
  • 나 스스로도 알지만 불충분했던 지식이나 아직 어렴풋한 지식을 설명하면서 함께 공부하고 배우기 위해

1.6.2. 김태진

  • 학교에서 배우기 힘든 다양한 지식(자바뿐만 아니고)들을 접해보고, 활용할 수 있기위해
  • 아직 내가 구현하는게 불가능한 것을 가능하게 하는 것부터, 좀 더 '잘' 구현하는게 가능한 영역까지 그 폭을 넓히기 위해
  • 어디가서 자바로 개발 좀 제대로 해봤냐라고 물어볼때, 확실히 '네'라고 대답할 수 있기 위해
  • 병특을 위한 중장기 프로젝트(?)
  • "내가 아무것도 모른 상태에서 1학년 1년간 배울때처럼 그때 그 마음으로 많은 것을 배우기 위해" - 배움에 이유가 있는가.

1.6.3. 서영주

  • 자바를 좀 대충 배운 감이 있어서 자바에 대해서 조금 더 확실히 알고 학교에서 가르쳐주는 것 외의 자바에 관한 지식을 조금 더 배우고 싶어서.
  • 언어에 관한 것 뿐만 아니라 유용한 라이브러리, 자바 개발 환경 등 개발을 더 빠르고 편리하게 할 수 있는 방법을 배우기 위해서.
  • 유닛테스트, mock 프레임워크 사용 등의 부분에 대한 실제 사용 예를 잘 알기 위해

1.6.4. 권순의

  • 학교에서 배운 자바보다 더 심도있는 걸 하고 싶었는데 능력이 안 되서 못했기 때문에
  • 보다 더 사고를 넓히기 위해
  • 공부란 것은 하면 할 수록 할게 많기 때문..

1.6.5. 서민관

  • 단순히 자바 언어에 대해서가 아니라 더 다양한 주제를 다루는 스터디이기 때문에 흥미가 있어서.
  • 토요일에 할 수 있는 활동들 중에서 시간 대 성능 비가 월등하니까 듣지 않을 이유가 없다.
  • TDD로 코드를 짜 보려다 실패해서 -_-;;; 어떻게 TDD로 코딩을 해야 하는지, 어떻게 리팩토링을 해야 하는지 듣고 싶어서.

1.6.6. 권영기

  • 자바 언어에 대해서 심도있게 공부해보고 싶어서.
  • 나의 시야를 넓히고 싶어서.
  • 토요일을 알차게 보내기 위해서.
    좋은 선행학습이다..

2. 규칙


3. 진행


3.1. 2012년 5월 5일

  • 오리엔테이션
    • 튜터가 생각한 이 스터디의 "무엇을?", "어떻게?", "왜?"를 자세히 소개하고, 튜티들이 원하는 "무엇을?", "어떻게?"에 대한 이야기를 나눴습니다.
    • 스터디 시간이 참여자들 각각에게 원하지 않는 시간 낭비가 되지 않도록, 언제라도 또다른 의견과 질문을 환영합니다.
  • "왜?"에 각자 서브섹션을 나누어 자신이 이 스터디를 통해 원하는 것을 적고, 스스로에게 동기부여를 해봅시다.

3.1.1. 후기


3.2. 2012년 5월 12일

  • SpringSource Tool Suite(Eclipse IDE)의 기본 설정과 프로젝트 설정에 필요한 기본적인 정보를 설명했습니다.
  • Eclipse JDT의 빌드 과정을 알아보고 Maven에서 라이브러리 의존성을 추가해보았습니다.
  • 클래스와 그 멤버에 적용하는 기본 modifier들의 개념 및 용법을 다뤘습니다.
    • public, protected, private, (none)
    • abstract, final, static

3.2.1. 후기


  • static modifier에 대해 애매하게 알고 있었는데 자세하게 설명해주셔서 좋았습니다. static은 타입을 통해서 부르는거라거나 원래 모든 함수가 static인데 객체지향의 다형성을 위해 static이 아닌 함수가 생긴거라는 설명은 신기했었습니다. object.method(message) -> MyType::method(object, method) 부분이 oop 실제 구현의 기본이라는 부분은 잊어버리지 않고 잘 기억해둬야겠습니다. 근데 파이썬에서 메소드 작성시 (self)가 들어가는 것도 이것과 관련이 있는건가요? -서영주
    • Python 은 PEP에 절대 권한을 가진 귀도가 그냥 의견을 모아서 정한겁니다. 원숙한 언어일수록 스펙 자체가 '원래 그런 것'은 없고, '사람간의 약속'입니다. 이하 참고자료. --NeoCoin
    • 제가 "원래 모든 함수가 static"이라는 의미로 말한건 아닌데 오해의 소지가 있었나보군요. 사실 제가 설명한 가장 중요한 사실은 말씀하신 예에서 object의 컴파일 타입의 method() 메서드가 가상 메서드라면(static이 아닌 모든 Java 메서드), 실제 어떤 method() 메서드를 선택할 것이냐에 관한 부분을 object의 런타임 타입에 의한다는 부분이었지요. 그러니까 object는 컴파일 타입과 동일하지 않은 런타임 타입을 가질 수 있으며, 다형성의 구현을 위해 implicit argument인 object(=this)의 런타임 타입에 따라 override된 메서드를 선택한다는 사실을 기억하세요. (Python에선 실제 메서드 내에서 사용할 formal parameter인 self를 explicit하게 선언할 수 있다고 보면 되겠지요.) - 변형진
  • static에는 이런 용법도 있습니다. StaticInitializer - 안혁준

3.3. 2012년 5월 19일

  • Singleton 패턴과 lazy initialization의 필요성에 대해 이야기했습니다.
    • 멀티스레드 환경에서 synchronized modifier를 사용한 동기화에 대해 공부했습니다.
    • 동기화 부하를 피하기 위한 DCL 패턴의 문제점을 살펴보고 Java 5 이후에서 volatile modifier로 해결할 수 있음을 배웠습니다.
  • Serializable 인터페이스와 ObjectOutput, ObjectInput을 사용한 직렬화, 역직렬화에 대해 공부했습니다.
    • transient modifier는 VM의 자동 직렬화 과정에서 특정 속성을 제외할 수 있고, Externalizable 인터페이스를 구현하면 직렬화, 역직렬화 방식을 직접 정의할 수 있음을 보았습니다.
  • JNI라는 기법을 사용해 네이티브 라이브러리를 연결하여 함수를 호출할 수 있음을 배웠습니다.
    • native modifier로 함수의 인터페이스를 선언할 수 있고, 마샬링, 언마샬링 과정에서 성능 손실이 있을 수 있음을 이야기했습니다.
  • 불변객체의 필요성과 조건에 대해 알아보았습니다.
    • 대표적인 불변객체인 String 클래스가 내부적으로 어떻게 구현되고, 어떻게 불변성을 유지하는 지를 살펴보았습니다.
      • 다양한 String 객체의 활용 과정에서 객체들의 동일성과 동등성을 알아보았습니다.

3.3.1. 후기

  • String객체라니..! 자바 스트링은 편하면서도 불편했는데 뭔가 그 이유를 들을 수 있었을 법한 주제네요..-김태진
  • c++에서 상호배제 관련으로 mutex나 critical section같은거 엄청 배웠었는데 자바에서는 synchronized를 이용해서 쉽게 처리할 수 있다는게 신기했습니다. os 수업 들은지 오래 됐는데 멀티프로세스와 멀티스레드 수업을 다시 들으니까 설명을 참 잘 해주셔서 좋았습니다. 함수에만 붙일 수 있는게 아니고 보호자원을 가진 객체를 이용한 synchronized(this){ ... } 같은 부분은 나중에 스레드를 쓸 경우에 참고가 될 것 같습니다. 그리고 인터페이스와 리플렉션을 이용한 초기화를 보니 생각을 잘 하면 구체클래스가 코드에 안드러나게 할 수 있다는 점도 볼만했습니다. -서영주
  • 개인적으로 synchronized는 잘 몰라서 그냥 붙이면 일단 된다는 이미지만 막연하게 가지고 있었는데 그런 부분까지 세밀하게 다뤄 주셔서 듣기에 상당히 좋았습니다. 그래서 깊이가 상당히 깊어졌다는 점은 장점도 있고 단점도 있었지만 제 입장에서는 그래도 어느 정도 들을 수 있었던 만큼 다룰 범위를 괜찮게 설정하시지 않았나 싶습니다. - 서민관

3.4. 2012년 5월 26일

  • interface
  • nested class
    • static nested class
    • inner class
    • annonymous inner class
  • 응집도up와 결합도dw (cohesion&coupling)
  • SOLID SOLID Wiki(http://en.wikipedia.org/wiki/SOLID_(object-oriented_design))
    • SRP (Single responsibility principle)
    • OCP (Open/closed principle)
    • LSP (Liskov substitution principle)
    • ISP (Interface segregation principle)
    • DIP (Dependency inversion principle)
  • DRY DRY Wiki(http://en.wikipedia.org/wiki/Don't_repeat_yourself)
    • dont repeat yourself(http://en.wikipedia.org/wiki/Don%27t_repeat_yourself) 이걸 걸려고 했나? - 서지혜
      • 이상하네요; 그냥 주소 복사해서 주소창에 넣으면 잘 뜨는데 -_-a - 권순의
        • url중에 '가 들어있어서 그런듯... - 서지혜

3.4.1. 후기

  • 딱 6시간 지나고 생각해보니 오늘 뭐 배웠더라.. 하는 느낌이 왔네요--; 중간에 잠깐 졸아서인지 저번시간에 반밖에 못들어서였을지.. 저작권 이야기는 좀 생각나지만 나머지는 뭔가 평소보다 더 여기갔다 저기갔다 하는 바람에 머리가 혼란스러웠나봐요;; -김태진
  • 전체적으로 다른 언어에서는 볼 수 없는 자바의 문법 + 객체지향 원칙을 중점적으로 다룬 시간이었습니다. 중간중간 다른 이야기들(builder 패턴, 저작권)이 들어갔지만 그래도 다룬 주제는 명확하다고 생각합니다. 다만 그걸 어떻게 쓰느냐는 흐릿한 느낌입니다. 그건 아마도 각 원칙들이나 interface, 객체 등에 대한 느낌을 잡기 위해서는 경험이 좀 필요하기 때문이 아닌가 싶습니다 ;;; 수경이가 말한 대로 한 번이라도 해 본 사람은 알기 쉽다는 말이 맞지 않을까 싶네요. 그리고 전체적으로 이야기를 들으면서 현재 프로젝트 중인 코드가 자꾸 생각나서 영 느낌이 찝찝했습니다. 세미나를 들으면서 코드를 생각하니까 고쳐야 될 부분이 계속 보이는군요. 그래도 나름대로 코드를 깔끔하게 해 보려고 클래스 구조도 정리를 좀 하고 했는데 더 해야 할 게 많은 느낌입니다. ㅠㅠ 그 외에도 이번 시간에 들었던 메소드의 책임이 어디에 나타나야 하는가(객체 or 메소드) 라거나 상속을 너무 겁내지 말라는 이야기는 상당히 뚜렷하게 와 닿아서 좋았습니다. 아. DIP에서 Logic과 native API 사이에 추상화 레이어를 두는 것도 상당히 좋았는데 기회가 되면 꼭 코드로 보고 싶습니다. 아마 다음에 보게 되겠지만. - 서민관

3.5. 2012년 6월 2일

  • Serialize
    • Abstraction layer
  • Inner Class, Nested Class(보강), Local Class, Static Inner Class
  • Iterator (java.util)
    • 우리가 아는 interface 사용
    • generics 사용
    • Collection 일반화, 순차적 순회, 대부분의 자료구조에서 O(1), 변경하지 않는 한 thread safe
    • but 중간에 변화에 있어선 그닥
  • Iterable (java.lang)
  • Iterator의 특징과 Iterable을 사용했을 때의 특징들을 공부하는 시간
  • Comparable
    • for Sorting.. stable, unstable

3.5.1. 후기


  • 지난시간에 이은 Inner Class와 Nested Class의 각각 특징들 Encapsulation이라던가 확장성, 임시성, 클래스 파일 생성의 귀찮음을 제거한것이 새로웠습니다. 사실 쓸일이 없어 안쓰긴 하지만 Event핸들러라던가 넘길때 자주 사용하거든요. Inner Class에서의 this는 Inner Class를 뜻합니다. 그렇기 때문에 Inner Class를 포함하는 Class의 this(현재 객체를 뜻함)을 불러오려면 상위클래스.this를 붙이면 됩니다. Iterator는 Util이지만 Iterable은 java.lang 패키지(특정 패키지를 추가하지 않고 자바의 기본적인 type처럼 쓸수있는 패키지 구성이 java.lang입니다)에 포함되어 있는데 interface를 통한 확장과 재구성으로 인덱스(index)를 통한 순차적인 자료 접근 과는 다른 Iterator를 Java에서 범용으로 쓰게 만들게 된것입니다. 예제로 DB에서 List를 한꺼번에 넘겨 받아 로딩하는것은 100만개의 아이템이 있다면 엄청난 과부하를 겪게되고 Loading또한 느립니다. 하지만 지금 같은 세대에는 실시간으로 보여주면서 Loading또한 같이 하게 되죠. Iterator는 통해서는 이런 실시간 Loading을 좀더 편하게 해줄 수 있게 해줍니다. 라이브러리 없이 구현하게 되면 상당히 빡셀 것 같은 개념을 iterator를 하나의 itrable이란 인터페이스로 Java에서는 기본 패키지로 Iterable을 통해 Custom하게 구현하는 것을 도와주니 얼마나 고마운가요 :) 여튼 자바는 대단합니다=ㅂ= Generic과 Sorting은 다른 분이 설명좀. - 김준석

3.6. 2012년 7월 20일

  • Java Generics
    • run-time의 type erasure
      • 프로그래머의 타입 보장
  • Reflection API
    • parameter 얻어오는 방법 세 가지.
      • public field
      • getter, setter가 존재하는 field
      • @property annotation 사용
  • Generics와 Reflection을 이용한 ObjectMapper 만들기
    • Map <-> Object 변환

3.6.1. 후기

  • 리플렉션과 제네릭스를 써서 map -> object와 object -> map을 하는 부분을 해봤습니다. 자바의 일반적인 세 가지 방식의 클래스 내 변수에 대해 getClass, getFields, getMethods를 사용해 private, 나 접근자가 있는 경우의 값을 받아왔습니다. getter를 사용해서 변수 값을 받아올 때 이름이 get으로 시작하는 다른 함수를 제외하기 위해 method.getParameterTypes().length == 0 같은 부분은 이렇게 체크해야 된다는 부분은 나중에 제네릭스 관련으로 써먹을만 할 것 같습니다. 그리고 mapToObject에서는 문제가 없었지만 objectToMap의 경우에는 제네릭스의 type erase때문에 Class<T> expectedType = T.class; 같은 코드를 사용할 수 없어서 map.put(field.getName(), (T)field.get(obj));에서 형변환의 타입 안전성을 위해 인자로 Class<T> valueType을 받아오고 valueType.isAssignableFrom(field.getType())로 체크를 하는 부분도 공부가 많이 됐습니다. - 서영주

3.7. 2012년 7월 27일

  • Annotation
    • Annotation의 생성 및 사용
      • 다른 Annotation을 붙이는걸로 확장 가능.
      • @Target : 만들고자 하는 Annotation의 대상 지정. (ElementType.TYPE, ElementType.METHOD)등
      • @Retention Annotation에서 나오는 정보가 언제 필요한가의 여부. (RetentionPolicy.RUNTIME) 등
  • 외부 라이브러리 사용
    • java.beans
    • apache.commons.lang
      • util함수들을 많이 제공함. 한 번에 결과가 나옴.
      • google의 guava는 함수의 체이닝을 많이 사용함.
      • 함수의 체이닝을 위해서는 generics가 필요함. static method로는 체이닝을 할 수 없음.

3.7.1. 후기

  • 웹 수업에서 prototype 설명 때도 그랬지만 먼저 개념적인 부분에 대해서 기본적인 구현이 어떻게 되어있는지를 먼저 배우고 이러한 기능들을 실제로 더 편하게 쓸 수 있는 라이브러리는 어떤 것들이 있는지 배우니까 그냥 라이브러리만 아는 것보다 조금 더 알기 쉬운 것 같습니다. 유용한 라이브러리들이 어떤게 있는지 더 많이 가르쳐주셨으면 좋겠습니다. Annotation은 매번 쓰기만 했었는데 이렇게 한 번 만들어보니까 생각보다 어렵지는 않은 것 같습니다. - 서영주

3.8. 2012년 8월 3일

  • ObjectMapper (cont.)
    • Class mapping by annotation
      • Annotation on concrete class
      • Annotation on superclass
      • Initilize ObjectMapper at runtime
    • Scan annotated classes in package
    • Pros and cons to use annotations
    • Concurrency
      • java.util.concurrent(.atomic)
    • LRU cache using LinkedHashMap

3.9. 2012년 8월 17일

  • ObjectMapper (cont.)
    • Data 부분을 인터페이스로 분리 - 내부에서 FactoryMethod 패턴을 사용. factory를 통해서 객체를 생성한다. new를 사용하지 않기 때문에 구체 클래스를 숨길 수 있다.
      • CsvData - data의 구체 클래스. 내부에서 속도의 향상을 위해서 역색인 방식을 사용.
  • Maven - 의존성(dependency)을 관리해 주는 툴. pom.xml에 프로젝트의 의존성 관련 정보를 적으면 저장소(repository)에서 관련 라이브러리 파일들을 받아서 빌드에 포함시켜 준다.
    • m2e plugin - maven과 eclipse는 빌드를 다른 방식으로 하기 때문에 maven의 의존성을 eclipse의 의존성과 연결해주기 위해서 사용하는 plugin.
    • 라이브러리 파일(jar) 만들기(Run as -> Maven Install) - ObjectMapper를 라이브러리와 클라이언트 프로젝트로 분리.
      • Windows7 기준으로 사용자이름\.m2\groupid\artifactid 폴더에 jar 파일을 만들어 준다.
      • 클라이언트 프로젝트에서 사용하고자 하는 라이브러리의 정보를 pom.xml에 추가 후 maven build를 실행.
    • Maven Build 과정
      • resources - src/main/resources 설정파일 등을 target/classes로 전달. javac를 사용하지 않는다.
      • mvn compile - src/main/java에 있는 소스파일을 컴파일해서 .class를 만들어 target/classes로 보낸다.
      • test-resourecs - src/test/resources의 설정파일 등을 target/test-classes로 전달.
      • mvn test - 컴파일을 하고 나서 src/test/java를 컴파일해서 target/test-classes로. @Test 실행 <scope>가 언제 사용되는지 결정
      • mvn package - 패키징. pom.xml의 <packaging>에 따른 파일 생성. 기본은 jar파일 생성.
      • mvn install - 패키징된 파일, pom을 .m2/repository에 집어넣는다.
      • mvn deploy - 리모트 리포지터리에 라이브러리 파일을 배포.
      • mvn release
    • resolve dependencies from workspace projects
      • 라이브러리 코드에 변경이 있을 시 maven install을 다시 하지 않으면 클라이언트 프로젝트에서 문제가 생길 수 있다.
      • 체크가 되어있을 경우 maven 의존성과 별개로 워크스페이스 안에 있는 프로젝트를 참조할 수 있게 해준다.
      • maven 의존성과 이클립스 의존성간의 차이가 발생할 수 있다.

3.10. 2012년 9월 22일

  • Properties
    • map과 비슷한 구조.
      • 값을 가져오는 함수를 getProperty와 get의 두 가지를 제공한다.
      • getProperty는 String을 반환, get은 Object를 반환 - 제네릭이 없었을 때에는 Object를 받아올 수밖에 없었는데 일반적으로 받아서 쓰는 값이 String이었기 때문에 사용자의 형변환을 피하기 위해 getProperty를 따로 제공했음.
  • Reader와 InputStream의 차이
    • 인코딩 문제의 차이. 인코딩 문제를 해결하기 위해서 Reader, Writer를 만들었다. Reader는 인코딩 정보를 들고있어야 한다.
  • JDBC - 각 데이터들에 대한 접근 표준 인터페이스
    • java.sql.driver 인터페이스를 com.mysql.jdbc.driver 클래스로 구현, java.sql.connection 인터페이스를 com.mysql.jdbc.connection 클래스로 구현
      • driver에서 connection을 얻어오는 부분에 대해서는 abstract factory가 사용됨 - 추상타입으로부터 추상타입을 만든다.

java.sql.Driver driver = new com.mysql.jdbc.Driver();
java.sql.Connection conn = driver.connect("", null); // 구현체 중 com.mysql.jdbc.connection을 반환.
//추상타입 객체인 driver로부터 추상타입 객체인 conn 생성
  • abstract factory를 잘 쓰기 위해서는 인터페이스에 api가 잘 설계되어 있어야 한다.
  • Statement, ResultSet에 대해서도 마찬가지로 인터페이스를 이용한 abstract factory가 사용됨.
  • driver의 설정에서 new com.mysql.jdbc.Driver(); 대신 볼 수 있는 Class.forName("com.mysql.jdbc.Driver"); 이러한 코드는 컴파일 타임 종속성을 런타임 종속성으로 바꾼 것이다.

Driver driver = new com.mysql.jdbc.Driver(); // 처럼 직접 구체클래스로 new를 하는 대신

Class<Driver> clazz = (Class<Driver>) Class.forName("com.mysql.jdbc.Driver");
Driver driver = clazz.newInstance(); // 같은 방법으로 런타임 종속성으로 바꿀 수 있음.
  • 예외상황을 런타임으로 밀어낸 것이기 때문에 에러에 대해서는 더 위험해질 수도 있다.
  • factory method 패턴 사용 - factory를 숨겨주는 메소드. 뭘 만들지를 인자만 가지고 결정하는 함수. 위에서는 인자로 주는 문자열에 따라("com.mysql.jdbc.Driver") 무엇을 만들어줄지가 결정된다.
  • DriverManager 클래스를 사용하면 직접 driver를 가져와서 connection을 얻어오지 않아도 바로 connection을 얻어올 수 있다. 이렇게 추상화를 해준 것이 DataSource 클래스.
  • sqlite
    • 기존의 dbms와 다르게 dbms가 각 어플리케이션 내부에 들어가서 동작하는 것.
    • 분산환경의 경우 os단에서 상호배제를 해주지 못하기 때문에 동시성 제어에 문제가 있을 수 있다. 따라서 분산환경에서의 사용은 좋지 못하다.

3.11. 2012년 10월 6일

  • DataSourceDriverManager의 차이
  • Persistence Layer
    • persistance layer는 외부 레이어를 많이 쓰기 때문에 예외가 많이 생김.
    • 이러한 예외가 비즈니스 로직까지 올라가게 하면 안됨.
    • 예외가 올라가게 될 경우는 예외를을 한 단계 추상화해서 올려주는 것이 좋다.
  • DataBase 정규화(Normalize)
    • 데이터를 테이블로 저장할 때 중복된 값이 있는 경우에는 테이블이 나눠져있는 경우와 비교해서 다른 테이블을 찾지 않아도 되기 때문에 검색 비용이 적다.
    • 하지만 중복된 값이 있는 경우에는 업데이트시 값이 있는 부분을 전부 찾아서 수정해야 하므로 업데이트 비용이 비싸다.
    • 반대로 데이터의 중복을 없애고 테이블을 나눴을 경우는 업데이트 비용이 줄어들고 검색의 비용이 늘어난다.
    • 업데이트와 검색은 트레이드 오프.
    • 정규화를 할 경우 테이블간의 중복된 값을 없앤다.
  • Builder 패턴
    • 빌더라는 가변객체를 만들어서 상태를 계속 변경시키고 마지막에 만든다. 그래서 중간에 체인을 하나씩 끊어도 된다. 가변체이닝 방식.


Resource resource = new JdbcResource.Builder()
.setUrl("jdbc:mysql://zeropage.org:3306/test")
.setUser("test")
.setPassword("test")
.setTable("people")
.create();
  • 위와 같은 체인식의 문법으로 설정을 추가해가며 마지막에 객체를 생성하는 방식을 사용한다.
  • 설정을 따로 빼내기 좋고, set을 private함수로 바꿔서 불변객체를 만들 수도 있다. 이렇게 할 경우 스레드 환경에도 조금 더 안전해진다.
  • 체인문법의 장점 - 체인을 쓸지 말지를 선택할 수 있다.

3.12. 2012년 10월 20일

  • uri와 url의 비교
    • uniform resource identifier와 locatord의 약자. uri가 url보다 더 큰 개념이다.
    • map에서 자료를 가져와서 equals로 비교를 할 때 url은 실제로 가져온 내용이 같은지 비교하고 uri는 식별자가 같은지만 비교한다.
    • url의 equals는 비교를 하려면 자료를 가져와야 하기 때문에 성능의 낭비가 심하다. 따라서 실제로 자료가 같은지 비교해야 할 때에만 url을 사용하는 것이 좋다.
    • url과 uri는 서로 toURI, toURL을 지원한다.
    • uri의 기준이 url의 기준보다 더 엄격하다.
  • abstract factory패턴과 factory method 패턴의 구분
    • 생성 메소드를 호출하는 인스턴스의 타입, 메소드에 들어가는 인자의 두 가지가 새로 생성되는 인스턴스에 영향을 주는 경우 abstract factory
    • 생성 메소드의 인자만으로 생성되는 인스턴스의 타입이 결정될 경우 factory method
  • abstract factory는 확장 위주의 패턴이다. 자바 프레임 워크에서는 api의 확장이 중요하기 때문에 자주 보이지만 일반적인 어플리케이션에서는 확장성을 제공할 필요성이 적기 때문에 많이 나타나지 않는다.
  • PushbackInputStream 클래스
    • lookahead inputstream. 기존의 input stream은 한 번 read하면 끝나지만 lookahead 버퍼를 가지고 있어서 한 번 read한 후에 다시 read하기 전의 상태로 돌아갈 수 있다.
    • 자바에서는 inputstream에 대한 지원이 많기 때문에 반환 결과를 inputstream으로 만들 수 있으면 처리가 쉬워진다.
  • strategy 패턴, command 패턴, template method 패턴
    • 행동을 확장하기 위한 패턴이다.
    • strategy 패턴 - command 패턴
      • strategy 패턴은 전체적인 틀(logic)이 짜여져 있고 그 안에 특정 행동을 확장하기 위해 전략 객체를 사용한다.
        반면에 command 패턴은 따로 틀이 없고 보다 범용적으로 사용된다.
    • strategy 패턴 - template method 패턴
      • strategy 패턴은 인터페이스로 만들어 둔 전략 객체 클래스를 구현(implementation)하는 방식으로 행동을 확장한다.
        반면에 template method 패턴은 부모 클래스에서 전체적인 틀을 만들어 두고 행동에 해당하는 메소드를 상속 + 오버라이드 해서 확장한다.

3.13. 2012년 11월 3일

  • ~let : 외부의 컨테이너에서 라이프사이클을 관리해주는 프로그램. 안드로이드의 activity같은 경우 외부에서 실행시켜서 동작하게 됨. 그것과 비슷한 것.
    • applet : 어플리케이션(브라우저)상에서 돌아가는 작은 프로그램.
    • servlet : 서버상에서 돌아가는 작은 프로그램. 아파치 웹서버의 모듈 방식(외부에서 http request가 날아오면 서버가 받아서 알맞은 모듈에 전달해줌.)처럼 만들어 놓은 것.
    • portlet : 포탈(관리프로그램 등)상에서 돌아가는 작은 프로그램.
  • javaSE, javaEE : java스펙의 집합.
    • javaSE : JLS(java language specification) + java api를 가리킴. 자바의 실제 문법과 언어에 필요한 기본적인 기능들. 참조 구현체로는 hotspot JVM이 있다.
    • javaEE : SE 이외의 표준 스펙들을 다 모아서 javaEE라고 함. javaSE 외의 추가적인 기능들이 들어감. javaEE에서 제일 잘 알려진 스펙이 servlet이다. 참조 구현체로는 tomcat과 glassfish가 있다. tomcat은 servlet의 스펙만 만족시키고 javaEE의 전체 스펙을 만족시키지는 않지만 glassfish는 javaEE의 모든 스펙을 만족시킨다.
    • tomcat은 servlet container지만 glassfish는 WAS(web application server)에 해당한다.
  • DIP (depencency inversion principle) : 구체클래스를 사용할 때 구체클래스를 직접 사용하지 않고 추상화 된 인터페이스를 통해서 사용하게 하는 디자인 패턴.
    • JPA의 구체 클래스로 eclipse link와 hibernate가 있는데, 각각을 사용할 때 구체 클래스를 통해서 사용하지 않고 JPA 인터페이스를 통해서 사용하도록 하면 나중에 구체 클래스를 바꾸기 쉽다.
  • tomcat에 servlet을 배포 시 내부의 동작
    • tomcat에 servlet을 배포하는 것은 servlet을 구성하고 있는 클래스를 tomcat의 클래스패스에 집어넣는 것을 말한다. java의 특성 상 tomcat이 실행된 이후에 클래스패스에 나중에 추가된 클래스를 집어넣어서 동적 로딩을 할 수 있다.
    • servlet의 war(web archive)파일을 넣어주면 tomcat내부의 watcher가 war파일의 정보를 읽어서 추가된 클래스를 동적으로 로딩해 준다.
    • servlet 클래스의 로딩 순서 : jvm에서 tomcat의 main클래스를 진입점에 로딩한다 -> deployment description에 언급되어있는 servlet클래스를 tomcat의 진입점에 로딩한다.
  • servlet 실행
    • template method 패턴이 사용됐다. protected로 선언된 service method가 template method에 해당되는데 abstract가 아닌 이유는 기본 구현을 주고 원하는 호출에 대해 오버라이드를 해서 사용하기 위함이다.
    • init : servlet이 불러와지면 먼저 실행되는 method. init이 실행되지 않으면 servlet이 로딩되지 않는다.
    • destoy : servlet이 종료될 시 실행되는 method.
    • service : 외부에서 서버로 request가 들어올 시 서버에서 servlet의 service method를 실행시킴. service(req, res) 내부에서 req를 통해 request의 값을 받아서 res의 값을 변경시켜 외부로 내보내준다. 해당 결과를 do*의 이름이 붙은 method(doGet, doPost 등)로 전달해준다.
    • do* : 해당 httpMethod에 대한 처리를 해주는 method.

3.14. 2012년 11월 10일

  • jar와 war의 차이
    • war : src/main에 있는 webapp 폴더 내부에 있는 파일이 root로 오게 된다.
      • src/main/java, src/main/resources 가 war의 WEB-INF 폴더 내부의 classes 내부에 위치하게 된다.
    • jar : src/main/java, src/main/resources 폴더가 root로 오게 된다.
  • http 요청이 servlet에 전달되기까지 과정
    • http요청(http://hostname/contextPath/path?params) -> contextPath를 보고 해당하는 war를 찾음 -> war 내부의 web.xml을 보고 <servlet-mapping>의 정보를 보고 해당 주소에 매핑된 servlet을 찾는다. -> 해당하는 servlet이 없을 경우 defalut servlet이 처리
  • servlet filter chain
    • request가 servlet으로 전달되기 전에 filter chain을 걸어서 여러 servlet에 일괄적인 동작을 해줄 수 있음.
    • request -> Servlet Container -> Filter -> Servlet
    • response <- Servlet Container <- Filter <- Servlet
  • servlet의 thread safety
    • servlet은 thread per request 구조로 하나의 servlet 객체가 여러개의 스레드에서 호출되는 구조.
    • filter, servlet은 하나의 객체를 url에 매핑해서 여러 스레드에서 쓰이는 것임. 따라서 thread-safe 해야 한다.
    • thread-safe하기 위해서는 stateful해서는 안 된다. Servlet이 stateless하더라도 내부에 stateful한 객체를 들고 있으면 결국은 stateful하게 된다. 자주 하는 실수이므로 조심하도록 하자.
    • 처리 방법 : 공유되는 변수를 쓰지 말고 함수 내에서만 사용하는 지역 변수를 사용하도록 하자,
      ThreadLocal을 사용한다. ThreadLocal은 각 스레드마다 서로 다른 객체를 들고 있는 컨테이너이다.

3.15. 2012년 12월 23일

  • IME(Input Method Editor) - OS 레벨에서 실제 key code - 문자의 mapping과 문자 조합('ㅁ' + 'ㅏ' 같은 경우)의 처리를 해 주는 소프트웨어. Sublime에서는 제대로 처리를 안 해 줬다...
  • JNI(Java Native Interface)
    • Java에서 다른 언어(C언어)로 된 라이브러리를 동적으로 호출해서 사용할 수 있도록 해 주는 방법.
    • 소스 코드의 컴파일 과정에서 load 과정에 해당하는 기술.
    • .java 파일에는 클래스 내에 native modifier를 붙인 메소드를 작성하고, .c, .cpp 파일에는 Java에서 호출될 함수의 구현을 작성한다. 이후 System.loadLibrary(...) 함수를 이용해서 .dll 파일(Windows의 경우) 또는 .so(shared object) 파일(Linux의 경우)을 동적으로 로드한다.
      • 라이브러리 파일의 함수는 특정한 naming convention을 지켜서 작성해야 하고, 인자도 반드시 몇몇 정해진 인자들을 받아야 한다. 또한 Java와 타입을 호환시키기 위해 C, C++에서 특정한 구조체들을 사용해야 한다. 해당 구조체들은 jni.h에 정의되어 있다.
      • 실제 사용하기에는 naming convention을 지켜서 함수를 작성하기는 귀찮기 때문에 native를 가진 .class 파일을 javah에 넣으면 convention을 지킨 .h 파일을 만들어 준다.
      • .cpp 파일로 작성했을 때 사용하는 extern "C"는 함수 호출 규약(__cdecl, __stdcall)과 관련된 부분이다. extern "C"를 적어주는 것으로 __cdecl로 함수를 호출하도록 한다.

3.16. 2013년 1월 6일

  • JVM & Java Byte Code
    • JVM - stack-based machine
      • register-based machine과의 차이는 연산에 사용되는 operand의 차이. register-based에서는 register에서 operand를 가져오고 stack-based에서는 stack에서 pop해서 가져온다.
      • stack-based machine의 경우 register-based machine에 비해 push, pop이 많아서 속도가 조금 느리지만 register를 사용하는 경우에 비해 기기에 덜 종속적이다.
      • 명령어의 prefix로 타입을 구분한다. http://en.wikipedia.org/wiki/Java_bytecode#Instructions
      • invoke* 명령어
        • invokespecial - vtable lookup을 하지 않고 메소드를 호출하는 경우. 어떤 메소드를 호출해야 하는지 정해져 있는 경우에 사용된다. new, private method, super 등.
        • invokevirtual - vtable lookup을 한다. 인스턴스의 실제 타입을 가지고 메소드를 찾는 경우. 대부분의 메소드들이 여기에 해당한다.
        • invokestatic - static 메소드 호출. 첫 인자로 this를 넣어주지 않는다.
        • invokeinterface - virtual과 거의 같다. interface의 메소드를 호출하는 경우에 사용한다.
      • if문 - if*과 if_*의 두 종류로 나뉜다.
        • if* 타입 - operand를 하나만 사용해서 0과 비교하는 경우가 대부분이다. ifeq(0과 같음), ifne(0이 아님) 등의 명령어가 있다.
        • if_* 타입 - stack에서 두 개의 operand를 꺼내서 서로 비교하는 경우에 주로 사용된다. if_icmpeq(정수형 값 두 개를 같은지 비교) 등의 명령어가 있다.

  • 11월 10일이 둘? - 서지혜
    • 복사해서 가져왔더니 날짜 바꾸는 걸 까먹은듯 ;;; - 서민관

Retrieved from http://wiki.zeropage.org/wiki.php/작은자바이야기
last modified 2021-02-07 05:30:42