2014년 5월 31일 토요일

Android 개발자로 일하기 위해서 필요한 지식들

한동안 안드로이드 앱 개발자로 일하면서 생각했던 단계별로 필요한 지식들, 안드로이드 개발을 막 시작한 부사수가 있다면 이런 과정을 거치도록 유도할 것이라고 생각했던 것들입니다.

1단계 - 아직 일 못 맡기지만 좋은 시작

2단계 - 간단한 작업은 맡겨도 됨

  • UI thread를 이해할 것
  • race condition, deadlock, visibility 등을 이해하고 위의 세 가지 문제가 없는 AsyncTask를 작성할 수 있을 것.
  • 코딩 원칙 체화 - 디자인 패턴, SOLID, 메소드 짧게 짜기, 한 메소드 내에서 각 statement 들의 추상화 정도가 비슷한 수준을 유지하게 하기 등등
  • Activity, Service의 라이프사이클을 이해하여 이 부분에서 문제가 되는 해괴한 코드를 짜지 않음. (static 변수에 의한 leakage예시가 대표적)
  • http://developer.android.com/guide/index.html 에 있는  내용을 대체로 숙지

3단계 - 같이 일하기 즐거운 동료

  • LOGCAT, adb shell top, hprof, 프로파일러 등등을 이용해서 메모리 사용, CPU-배터리 사용을 최적화할 수 있음
  • Mark and Sweep 을 이해하고, Activity 내의 static 변수가 발생시킬 수 있는 과도한 메모리 사용, 비트맵의 recycle() 이슈 등 이미 잘 알려진 메모리 관련 이슈들을 알고 있음.
  • 최신 유행하는 오픈소스 라이브러리 동향을 파악하고 있음. 이미지 로더 짜놓고 나서 volley를 발견한 멍청하고 아픈 과거가 있음.
  • jni 를 이용하여, 네이티브에서 자바 오브젝트와 메소드을 접근하여 사용할 수 있음

4단계 - 내가 배워하는 분들

  • Android 내부를 잘 이해하여 zygote, Binder 등을 막힘 없이 설명할 수 있음.
  • aidl을 활용함
  • GC의 동작 특성을 이해하여 locality를 고려한 코드를 짤 수 있음

2014년 5월 2일 금요일

emacs + Golang

go-settings.el

(add-to-list 'load-path "~/.emacs.d/go-mode" t)
(require 'go-mode-load)

(add-hook 'go-mode-hook (lambda ()
                          (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)))
(add-hook 'go-mode-hook (lambda ()
                          (local-set-key (kbd "C-c i") 'go-goto-imports)))
(add-hook 'before-save-hook 'gofmt-before-save)

(add-to-list 'load-path "~/.emacs.d/go-autocomplete" t)
(require 'go-autocomplete)

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(magit-item-highlight ((t nil)) t))

;; go-flymake & go-flycheck
(add-to-list 'load-path "~/.emacs.d/go-flymake")
(require 'go-flymake) 

 

 .emacs 에 추가될 사항

(load "~/.emacs.d/go-settings")

2014년 4월 24일 목요일

TDD 단상

어제밤 중에 TDD 이야기가 나온 김에 그냥 내 삽질 끝에 내린 생각 정리.

테스트를 먼저 작성
켄트 백의 책이 던진 충격 중에 가장 도발적이고 강력한 것이 이것이 아니었을까 생각한다.

"아직 아무 코드도 없는 상태에서, 실패할 테스트를 먼저 작성한다."

이것이 가지는 부수적인 효과는 다음과 같은 것들이라고 생각한다.

 1. 코딩에 들어가기 전, 어떤 인터페이스, 다시 말해서 어떤 인풋과 어떤 아웃풋을 가져야 할지를 먼저 생각하고 코딩에 들어가게 한다. 다시 말해서 내부 구현이 아니라 behavior에 의존하는 코드를 짜도록 강요한다.
 2. 매 다음 단계마다 테스트가 작성되므로 테스트가 각 '단위별'로 만들어지게 된다.
 3. 2의 여파로 각 단위가 고립되서 테스트되어야 하고 결과적으로 디커플링이 중요한 문제가 된다. 나는 mock을 이용하는 테스트가 멋지다고 생각한다.

이것들은 모두 좋은 디자인을 강제하는 방법으로 보였었다. 어떤 면에서는 전통적이라고 볼 수 있는 부분들도 있다. 나는 C를 A book on C, The C Programming Language 등으로 했었는데, 이 시절의 책들에서 실제 코드를 하기 전에 하도록 권유하는 것은 (테스트 작성은 아니고) 주석 작성이었다. 이것이 결국 인터페이스를 먼저 생각하라, 구현보다 인터페이스에 의존해라 등의 가르침이 아닌가? TDD는 이에 더불어 자동화된 테스트를 보유함으로써 리팩토링과 동전의 양면을 이룬다. 테스트될 수 있기 때문에 바꿀 수 있다.


나는 코드의 한 부분에서나마 이것들을 모두 지킬 강인한 의지가 있다면 충분히 경청할만한 방법이라고 생각한다. 그러나 당연히 만능이 아니다. 나는 그 한계를 내적인 것과 외적인 것으로 구분한다.


내적인 것은 TDD 자체가 가진 한계다. TDD는 함수, 프로시져, 메소드 단위에서는 좋은 디자인을 강요한다. 그러나 어떤 메소드가 어느 클래스에 속해야 하는지, 그 관계가 정확한 메타포를 형성하는지를 생각하도록 강제하지는 않는다. Car 클래스에서 drive()를 가져도 되는가? Driver클래스는 따로 만들어서 drive()는 Driver가 하는 것이 나을 것이다. 그러나 drive()의 테스트를 작성하는 순간, 그 사람은 drive()의 인풋과 아웃풋에 대해서 고민하겠지만 drive()가 Car에 속하지 않도록 강제하는 단계가 뚜렸하지는 않다고 본다.

외적인 것은 외부적인 상황 때문에 마주치는 한계이다. 대표적으로 GUI 프로그래밍의 경우 현재까지 사용자 인풋을 자동화하는 뾰족한 방법이 나왔다고는 보기 힘들다.  쓰레드 safety 문제도 TDD가 적절한 해법이 되기 힘들다고 보는데, 사실 이 외적인 한계들은 내적인 한계와 완전히 무관하지는 않다. 하나의 메소드가 synchronous 하게 인풋을 아웃풋으로 전환시키는 상황을 벗어나는 테스트는 본질이 아니기 때문이다.

이러한 "쓰면 되레 손해인 영역들"을 경험으로 확인해 나가고 쌓이는 것이 결국 TDD로 이득 보는 것을 가능하게 할 것 같다.

UEFI-GPT 부팅환경에서 페도라가 자동 생성하는 파티션

sda                                                                 
├─sda1 vfat                     8ABA-40EB                            /boot/efi
├─sda2 ext4                     cc7ef53e-c22c-438b-a070-3063822e020a /boot
├─sda3 swap                     3e8be53f-78c9-40b7-8f03-603a3b480fc8 [SWAP]
└─sda4 btrfs  fedora_isyru-e135 87837358-656a-4cb4-80d7-740e80af83a0 /

 
 Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          411647   200.0 MiB   EF00  EFI System Partition
   2          411648         1435647   500.0 MiB   0700
   3         1435648         8808447   3.5 GiB     8200
   4         8808448       976773119   461.6 GiB   0700  


Arch, Gentoo같은 배포판 설치할 때 파티션을 어찌 설치해야 할지 모르는 상황에서 참고하기 위해서 씀.

2014년 4월 13일 일요일

emacs에서 git라면 역시 magit!!

emacs에서 git 사용은 당분간 magit로 쓰는 걸로 결정.

정확한 상황은 모르지만 emacs의 vc인터페이스가 기본적으로 git의

working directory - stage - commit

구조에 딱 들어맞지 않게 생겨 있는 게 아닌가 하는 생각이 들고, vc-git나 emacs-git나 이 문제에 있어서는 매한가지인 것으로 보임.

옵션 뒤지면 다 나올 수도 있겠으나, 뒤져야 나오는 건 그 자체로 문제.


그래서 당분간 magit를 쓰기로 했습니다. 우분투, 페도라 두 배포판 모두에서 제공됩니다.

2014년 3월 11일 화요일

my .emacs

(require 'color-theme)
(color-theme-initialize)
(color-theme-gnome2)

;;; ~/.emacs 에 다음을 수정 또는 추가하세요
(custom-set-variables
'(default-input-method "korean-hangul390")) ;; 세벌식 390



go-mode 설치 파트는 일단 패스

2014년 2월 20일 목요일

God

I am not now, nor have I ever been, a member of the demigodic party.

-dmr