2020년 5월 5일 화요일

Android Room을 사용하여 DB에 데이터 저장

일반적으로 android에서 app을 만들 때 DB 사용은 필요함.

기존에는 SQLite를 사용하여 data class를 읽고 쓰고 할 수 있는 Generic DB access hander 같은 것을 만들었는데 이제는 Android에서 이를 지원한다.

Android Jetpack에서 Room이 여기에 해당되며
SQL의 Abstraction layer로서 쉽게 DB를 사용 가능하도록 해준다.
단 코드 기반 Room class 생성으로 로직 수정 시 빌드가 필요하다.

Room 개요

https://developer.android.com/training/data-storage/room


프로젝트 설정

https://developer.android.com/jetpack/androidx/releases/room#declaring_dependencies

주의해야 할 것이 있는데 kotlin을 사용한다면 kapt를 사용해야 하고 kotlin-kapt 플러그인을 추가해야 함. 종속성 예시 아래에 별표로 알려주고 있는데 이를 미처 보지 못해서 실행 중 죽는 현상이 발생하여 원인 찾느라 고생함.

build.gradle의 상단에
apply plugin: 'kotlin-kapt'

를 명시하고 dependencies예제를 추가하되 annotationProcessor 대신 kapt를 사용함.

 def room_version = "2.2.3"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

kotlin에서 수정없이 사용하면 아래 에러 발생됨.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: X.X.X, PID: 13160
    java.lang.RuntimeException: cannot find implementation for X.X.X.MyDatabase. MyDatabase_Impl does not exist
        at androidx.room.Room.getGeneratedImplementation(Room.java:94)
        at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:952)


구현

Room을 사용하여 로컬 데이터베이스에 데이터 저장
https://developer.android.com/training/data-storage/room
를 따라하면 쉽게 구현할 수 있음.

주요 annotation은
@Entity - DB에 저장할 data class/object
@Dao - DB를 사용 시 필요한 interface 정의
@Database - DB class, DB class 인스턴스화 시 DB가 생성되므로 아래 가이드 처럼 Singleton pattern class로 만들어야 함.

참고: 앱이 단일 프로세스에서 실행되는 경우 AppDatabase 개체를 인스턴스화할 때 싱글톤 디자인 패턴을 따라야 합니다. 각 RoomDatabase 인스턴스는 리소스를 상당히 많이 소비하며 단일 프로세스 내에서 여러 인스턴스에 액세스할 필요가 거의 없습니다.

비동기 호출

Room 사용 시 DB transaction이 꽤 시간이 소요 되므로
UI thread에서 직접 호출할 수 없어 비동기적 방법을 사용해야 함.
기존 Android에서는 AsyncTask 같은 것을 사용했었지만 Coroutine을 사용할 수 있음.

https://kotlinlang.org/docs/reference/coroutines-overview.html
https://developer.android.com/topic/libraries/architecture/coroutines


아래 article도 참고할 만함.
https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5



2020년 4월 20일 월요일

생체 인증을 위한 CheckboxPreference 만들기

개인적으로 만드는 app에서 생체 인증을 사용하고자 하여 
생체인증 enable/disable을 위한 CheckboxPreference로 옵션을 만들고 
옵션을 변경할 때마다 생체 인증을 하도록 간략히 만들어 봄

사실 너무 간단한 내용이라 안드로이드 가이드만 봐도 충분하다. 


내가 구현하고자 했던 것은
- 생체 인증을 enable/disable 하는 옵션
- 생체 인증을 통해서만 옵션을 enable<->disable 할 수 있음
- 생체 인증 실패 시에는 옵션 변경 없고 에러 발생 시 토스트 표시


안드로이드 생체인증 가이드를 기초하여 구현을 간략히 설명하면

1. 먼저 생체 인증을 위한 jetpack 라이브러리를 사용하고자 종속성을 추가한다.
 : 현재는 1.0.1 이다. 항상 Jetpack 라이브러리의 최신 버전을 확인해야 할 필요 있음.
dependencies {
        implementation 'androidx.biometric:biometric:1.0.1'
    }

2. app 설정에서 CheckboxPreference 추가

<CheckBoxPreference app:iconSpaceReserved="false"
 android:defaultValue="false"  
 android:key="pref_enableBiometricSignIn"   android:summary="@string/settings_summary_entry_enable_biometric_sign_in" 
 android:title="@string/settings_entry_enable_biometric_sign_in" />


3. CheckboxPreference의 onPreferenceChangeListener에서 BiometricPrompt 표시

val biometricCheckBox = findPreference("pref_enableBiometricSignIn") as CheckBoxPreference biometricCheckBox.onPreferenceChangeListener = OnPreferenceChangeListener { preference, newValue ->

 val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Biometric login for app")
    .setSubtitle("Log in using your biometric credential")
    .setNegativeButtonText("Cancel")
    .build()
 val toBe = newValue as Boolean
 val biometricPrompt = BiometricPrompt(this, Executors.newSingleThreadExecutor(),
  object: BiometricPrompt.AuthenticationCallback() {
 
  override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
    super.onAuthenticationError(errorCode, errString) activity ? .runOnUiThread {
     Toast.makeText(activity ? .applicationContext, errString, Toast.LENGTH_SHORT).show()
    }
   }

   override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
    super.onAuthenticationSucceeded(result) activity ? .runOnUiThread {
     (preference as CheckBoxPreference).isChecked = toBe
    }
   }
  }) 

 biometricPrompt.authenticate(promptInfo) 
 false
}


안드로이드 가이드 코드를 거의 그대로 사용하였고 원하는 기능을 위해 아래 사항을 살짝 수정함

- 생체 인증에 성공 시에만 옵션의 check status를 변경하고자 OnPreferenceChangeListener 구현
 : 생체 인증 시에만 check status를 변경하고자 OnPreferenceChangeListener의 리턴값을 false로 전달
 : 생체인증 성공시에만 isChecked 값을 OnPreferenceChangeListener의 argument인 newValue로 설정

- 사용자가 옵션을 변경할 때마다 생체 인증 창을 띄우기 위해 Executors.newSingleThreadExecutor() 로 Executor 매번 생성
 : 솔직히 이게 맞는 것인지는 모르겠음 ㅜㅜ

- 생체 인증 중 지문이 틀릴 때마다 호출되는 onAuthenticationFailed() 를 override하지 않고 onAuthenticationError() 만 override하여 사용자가 Cancel 하였을 때만 처리함 
 : 사용자가 생체 인증을 여러 번 틀려 block될 경우 BiometricPrompt에 안내가 표시되고 OnAuthenticationError()가 호출되기만 하고 사용자가 직접 cancel을 눌러야함.
 : block된 상황에서는 BiometricPrompt를 닫고 다시 옵션을 누르더라도 생체 인증창이 뜨지 않고 OnAuthenticationFailed()가 호출됨. 

2020년 4월 15일 수요일

OAuth 2.0 Authorization Framework

https://archive.org/details/mastering-oauth-2.0/mode/2up


상식선에서 대충 정리함.
자세한 것들(header, field, flow 등)은 rfc 참고 필요


OAuth 2.0은 Authorization framework로서
HTTP 서비스에 대한 액세스 권한을 얻기 위해
애플리케이션 승인 상호 작용을 정의하여
타사 애플리케이션이 자체적으로 리소스와 HTTP 서비스에 접근할 수 있도록 함.


먼저 인증(authentication) 인가(authorization)의 차이점

https://hanee24.github.io/2018/04/21/authentication-authorization/

인증(authentication)은 자신이 누구라고 주장하는 사람을 확인하는 절차이다. 권한부여(authorization)는 가고 싶은 곳으로 가도록 혹은 원하는 정보를 얻도록 허용하는 과정이다.

OAuth 2.0의 Authorization Grant 종류

. Authorization code grant (인증 코드 기반 인가)
. Implicit grant (암시적 인가)
. Resource Owner Password Credentials Grant
. Client Credentials Grant


클라이언트별 신뢰성에 따라 권고되는 인가 절차가 다름
. 신뢰 클라이언트 => 인증 코드 기반 허가
. 비 신뢰 클라이언트 => 암시적 허가

각각의 인가 절차는 
인가 코드 허가 절차
 - 서버 사이드 플로우이며
 - 복잡, 안전, 장기간
암시적 허가 절차
 - 클라이언트 사이드 플로우
 - 단순, 보안성 낮음, 단기간


OAuth 2.0 기반 client 개발 절차

1. 클라이언트 앱 등록
2. 액세스 토큰 얻기
3. 액세스 토큰을 이용하여 보호된 리소스 접근
4. 액세스 토큰 갱신

클라이언트 앱 등록 시 서비스로부터 다음 정보를 받게 됨
. Client ID
. Client secret
. Redirection endpoint
. Authorization endpoint
. Token endpoint



참고로 spec에서 말하는 용어들은 다음과 같다.

  • Resource Owner : 사용자로서 리소스의 접근을 허가함.
  • Resource server : 리소스를 보호하는 서버로서 acces token을 통해 리소스 요청을 허가한다.
  • Authorization server : 사용자로의 인증, 인가를 통해 access token을 client에 발급하는 서버 
  • User-agent : 웹 브라우저

Implicit Grant, 암시적 허가 절차



  • Implicit Grant 절차는 일반적인 client가 redirection URI를 사용하여 access token을 가져올 때 사용된다. 
    • client는 일반적으로 JavaScript를 이용하여 browser 내에서 동작한다.
  • Redirection 기반이므로 client는 리소스를 제공자의 user-agent(웹브라우저)와 연동 가능해야 하고 authorization server로 전달되는 요청을 받을 수 있어야 한다.
  • Authorization 수행과 access token 획득을 위해 각각 요청하는 uthorization code grant 절차와 달리 본 절차는 client가 authorization 수행의 결과로 access token 획득하게 되고 access token은 redirection URI에 포함되어 전달되므로 노출될 수 있는 점을 고려해야 한다.   


     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+

   Note: The lines illustrating steps (A) and (B) are broken into two
   parts as they pass through the user-agent.

                       Figure 4: Implicit Grant Flow


(A) 아래 client는 User-Agent(웹브라우저) 상에서 원하는 resource(정보, API) 접근 허가를 받고자 
identifier, requested scope, local state, redirection URI를 Authorization Server로 전달한다.
(B) 사용자가 User-Agent(웹브라우저)에서 인증(로그인 등) 하게 되면
(C) Authorization Server에서는 client에서 전달받은 redirection URI로 이동시킨다. 
     이때 URI에 access token이 (parameter 형태로) 포함된다.
(D)(E)는 client가 web hosted 기반인 상황에 해당하는 절차이고
(F) User-Agent(웹브라우저)에서는 URI 이동을 감지하여 access token을 추출한다.
(G) Client에 access token을 전달한다.

절차가 다르게 설명되어 있지만, Mastering OAuth2.0 책 삽화를 보면 이해하긴 쉬움.






Authorization Code Grant, 인증 코드 기반 허가 플로우

https://tools.ietf.org/html/rfc6749#section-4.1


  • Authorization Code Grant는 access token과 refresh token을 받기 위해 사용되며 신뢰할 수 있는 client를 대상으로 한다. 
  • Redirection 기반이므로 client는 리소스를 제공자의 user-agent(웹브라우저)와 연동 가능해야 하고 authorization server로 전달되는 요청을 받을 수 있어야 한다.


     +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)

   Note: The lines illustrating steps (A), (B), and (C) are broken into
   two parts as they pass through the user-agent.

                     Figure 3: Authorization Code Flow

 

(A) 아래 client는 User-Agent(웹브라우저) 상에서 원하는 resource(정보, API) 접근 허가를 받고자 identifier, requested scope, local state, redirection URI를 Authorization Server로 전달한다.
(B) 사용자가 User-Agent(웹브라우저)에서 인증(로그인 등)을 하게 되면
(C) Authorization Server에서는 client에서 전달한 redirection URI로 이동시킨다.
     이때 URI에 authorization code가 (parameter 형태로) 포함된다.
     User-Agent(웹브라우저)에서는 redirection URI 변경을 감지하여 authorization code를 추출하여 Client에 전달한다.
(D) Client는 access token을 발급받기 위해 전달받은 authorization code와 redirection URI을 Authorization Server로 전달한다.
(E) Authorization Server는 client를 인증, authorization code 유효성 확인, redirection URI가 (C)에서 사용된 것과 동일한지를 확인한 뒤  access token를 (필요 시 refresh token도 함께) 전달한다.

Mastering OAuth2.0 책 삽화를 참고




액세스토큰
. 클라이언트가 보호된 리소스에 일시적으로 접근할 수 있도록 해주는 형식이 정해지지 않은 문자열.
. 특정 범위의 권한으로 일정 기간 접근 할 수 있도록 해주며 서비스 제공자가 액세스 토큰의 권한 범위와 유효기간을 결정한다.
. 서버로 전달은 주로 다음 방법을 통해 가능
 : 인가요청 헤더 필드에 담아서 전달
 : 인코딩된 폼의 파라미터로 전달
 : URI 질의 파라미터로 전달


액세스토큰 갱신(refresh)

. 리프레시 토큰 워크플로우
. 인가 프로세스를 다시 시작하여 갱신 가능함.

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token
화질이 좋진 않지만 액세스토큰 갱신 시 절차를 나타낸 diagram임
위에서 말한 것과 같이 액세스토큰이 만료되는 경우
리프레시 토큰을 사용하여 갱신이 가능하지만
리프레시 토큰이 없다면 인가 절차를 다시 수행해야 함.



보안을 위해 고려해야 하는 사항들은 다음과 같다. 
(Mastering OAuth2.0 책 내용)


  • TLS를 사용하라
  • 최소한의 범위만을 요청하라
  • 암시적 그랜트 플로우를 사용할 때는 읽기 전용 권한만을 요청하라.
  • 사용자의 손이 미치지 않는 곳에 자격증명과 토큰을 보관하라 
  • 가능하면 항상 인가 코드 그랜트 플로우를 사용하라
  • 가능하면 항상 리프레시 토큰을 사용하라
  • 내장 브라우저 대신 네이티브 브라우저를 사용하라
  • 리다이렉션 엔드포인트에서 서드파티 스크림트를 사용하지 말라
  • 클라이언트 자격증명을 바꿔서 사용하라

2020년 3월 18일 수요일

나는 LINE 개발자입니다 : 라인의 개발 고수 12인의 도전과 기회, 성장의 개발 라이프

나는 LINE 개발자입니다 : 라인의 개발 고수 12인의 도전과 기회, 성장의 개발 라이프
강윤신,김영환,김재석,김정엽,김택주 저 외 7명 | 한빛미디어




궁금해서 읽어 봤는데 결국 LINE 홍보 도서 같다.
참고로 머리말에서 이렇게 언급하고 있다. 
"이 책은 흔한 자기개발서가 아니다. 기술 서적은 더더욱 아니다. IT기업에 합격이 잘되기 위한 절대 무공비급이 들어 있는 것도 아니다
...
라인에서 동료들과 함께 개발자로서 또 한던계 성장하고 도전하면서 느끼도 배운 경험담을 통해 개발자를 꿈꾸는 이 땅의 청년들에게 비전을 보여주고 꿈과 희망을 전달하고 싶었다."

저자의 경력과 분야가 다양하여 개발자를 꿈꾸거나 개발자인 사람들이 읽고 여러 분야를 간접 체험할 수 있을 것으로 생각된다.

하지만 읽고 나면 라인 뽐뿌가 상당하니 조심해야 할 듯 ㅎ

2020년 1월 22일 수요일

Galaxy Watch용 Tizen xamarin app에서 Entry에 의한 화면 깨짐 발생 시

Galaxy Watch app을 Xamarin.forms를 이용해서 C#으로 만들 수 있음.
https://samsung.github.io/Tizen.CircularUI/guide/Quickstart.html
기존에는 어려운 EFL 기반 app이나 web app을 만들어야 했는데 이제는 C#으로도 개발할 수 있음.

암튼 Watch 용 app을 하나 만들어 보는 중에
입력을 위한 Page가 필요하여 Entry를 추가하게 되었음.

하지만 페이지에서 Entry를 선택하면 Virtual Keyboard가 떠서
Page layout 밀려 올라가 이상하게 보이는 현상이 발생했다.

관련하여 다른 옵션이 없는지 확인 중 Tizen에서 제공하는 CircularUI가 있고
그 중에 PopupEntry를 제공하는 것을 확인하였음.

https://samsung.github.io/Tizen.CircularUI/guide/PopupEntry.html

Popup Entry는 일반적으로 Galaxy Watch app에서 사용되는
전체화면을 가리는 popup으로 입력창과 키보드가 떠서
기존 Page layout에는 영향을 주지 않고 입력할 수 있게 해준다.





참고로 안드로이드에서는 다음과 같이 처리하고 있음.
https://www.milestre.nl/blog/blogitem/milestre-blog/2019/01/08/to-avoid-soft-keyboard-overlap

//To avoid soft keyboard statusbar overlap            Xamarin.Forms.Application.Current.On().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

2019년 10월 31일 목요일

DEVIEW 2019 Day2 참가 세션 메모

세션에 참가해서 필요한 내용이나 기억에 남길 것을 메모함. 자세한 내용은 발표자료 참고.



[Multi-Tenancy Kubernetes on Bare-Metal Servers (네이버 컨테이너 클러스터)]


이팀은
. Container oriented : 베어메탈, 컨테이너 오케스트레이션
. Cost efficient : 범용서버 직접 구축
. Help containerize : 컨테이너 클러스트 + 레지스트리, 모니터/로깅, 교육,가이드 등 컨테이너화를 촉진하는 활동

효율적인 컨테이너 적용하려고 노력함 > Multi-Tenancy Kubernetes 로 불림
= 하나의 Kubernetes를 namespace로 나눠서 제공하는 것

Pros
. 모든 사용자가 Kubernetes자체 서버를 보유할 필요 없음
. 모든 사용자를 의한 여유 리소스를 보유할 필요 없음.
. 모든 사용자가 직접 Kubernetes를 운영할 필요 없음
Cons
. 신뢰성 있는 유저 필요
. 사용자가 Kubernetes의 모든 기능을 사용 할 수 없음
. Kubernetes가 매우 커지고 사용자도 많아서 운영하기 힘듬



현재 네이버
12+ 클러스터, 300+ 네임스페이스, 1000+ 유저
가장 큰 싱글 클러스터에 5000+ 팟 10000+ 컨테이너

2019 목표 => Elastic, efficient

Elastic한 서빙
.대규모, 실시간, 신뢰성

Efficient한 리소스 활용
.리소스 여구량, 시간대별 사용령이 모두 다름
.여유 리소스 최소화
.서버 대수 최소화 

로드밸러스 지표는 전체의 5% 수준 
> 800+ 200mac 32kcps 3G througbput

Kubernetes
대규모 클러스터 (20 node vs 500 node)
. 다수 클러스터 노드 관리, 관리서버(ETCD, api server) 과부하, 복잡해지는 관리시스템

사용 제한 
. 클러스터 영향을 주는 API 제한, 클러스터 전체에 적용되는 권한 제한 > 오픈소스 활용 걸림돌(노드/클러스터 분리, 전체 적용)

다양한 요구사항을 Affinity/Anti affinity 로 해결
. 노드 분리(private node 등), 리소스 장애 예방(리소스 부족 노드에 anti affinity 적용)

Runtime의 리소스 제한
. LimitRange 정책으로 container/pod의 리소스를 제한 (cpu 0.1 min 4 8 max), request는 limit 비율에 맞춰

Namespace Quota로 사용자별 허용 리소스 제어

Rescheduling
.long run pod이 많은 노드의 리소스 부족
.사용자가 request/limit을 잘 설정 안함
.스케줄러가 똑똑하지 않은 것 같음
> 심할경우 강제로 pod?를 죽임

자동제공 모니터링
.Prometheus/grafana provisioning 잘 정리된 텝플릿 제공
.kube event를 사용자가ㅜ 인 할 수 있도록

내년에
Network,resouce, runtime에 대한 isolation
Kubernetes Reliable Engineering + SRE
보다 많은 Cloud Native 서비스로 네이버의 경쟁력을 향상하도록


ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[안드로이드 앱의 다중 웹뷰 환경에서 성능 병목 진단 및 최적화 사례]


웹브라우저 엔진 vs 시스템 엔진
. 웹뷰 파편화 vs 유지보수 비용
. 웹뷰를 내장 시 크기 증가 vs 플랫폼은 버전별 피쳐 다름

XWhale 
. Crosswalks 계승
. 시스템 웹뷰 대체
. 네이버앱과 네이버 카페


사용성개선을 위한 다중 웹뷰 활용 

. 앱 초기화 시 복수의 웹뷰 사전 생성
=> 백그라운드 로딩 및 렌더링 수행으로 반응성 개선 예상

다중 웹뷰 생성에 따른 부담
. 브라우저 엔진 초기화
. Renderer 프로세스 생성 
. 웹뷰 생성 
. 웹페이지 로딩 

웹뷰 생성 측면
.웹뷰 생성 지연 이슈
.웹페이지 로딩 지연 이슈 (IPC로 인해 navigation이 시작되기전 지연)
>비동기 웹뷰 초기화 400ms, 백그라운드 웹뷰 초기화 지연 400ms

웹페이지 로딩 성능 측면
각 주제판에서 동일 css 파싱 시 시간 소모
. Loading은 caching되지만 parsing은 caching이 안됨
비용이 높은 js 문제
. Layout의 큰 변화를 야기하는 js
. DOM 전반에 대한 전면적인 변경
> rendering reschdule는 의미 없음 



성능지표?
. W3C navigation timing APi5 
. RAIL 성능 모델 
 : Response, Animation, Idle, Load
. First meaningfulpaint 
 : First meaningful paint : 페이지 layout이 급격히 변하는 순간
. Time to interactive 
. User metrics histogram 
 : chrome 브라우저에 실행정보가 누적된 in-memory DB, cache hit ratio 확인 가능

HTTP cache의 맹점
이미지 로딩 부하

성능 개선 방안
. Background 웹뷰 생성 지연 
 > 다른 리소스로 인해 종료 시간은 동일
. 브라우저엔진 비동기 초기화
 > thread 생성 overhead, callback의존성으로 효과 미비
. Priviligded HTTP cache 구현 
 > 지정된 URL 패턴, 지정된 referer, 지정된 resource type에 대해서 보존 기간 보장
 > image cache hit ratio 14%, paint 30-40m 향상
 > lower tier에서 80-120ms 개선 효과
. Cross Webview CSS cache 구현
 > Render 프로세스가 모든 웹뷰 접근(global cache)
 > css rule set은 웹페이지의 라이프사이클과 맞춤
 > 466ms의 CSS parsing이 한번만 발생
. Proxy기반 이미지 최적화
 > 디바이스 디스플레이 파편화에 대응이 어려움
 > 실제로 화면에서 보여주는 사이즈가 그림 사이느보다 커서 그닥..

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[앱 패러다임 변화 어떻게 적응할 것인가? (모듈 중심의 안드로이드 앱 설계)]


뭐가 변했는가?
Hardware(멀티코어, 드양한 디스플레이) 
Platform 
. Dalvik->JIT/ART 
. APP Bundle(Dynamic Feature & Delivery) 
Language (FunctionalProgramming, kotlin)
다양한 프레임워크 
. JetPack 
. RxJava 
. Lottie 
. Retrofit 
. Glide, Picasso, OkHttp 

좋은 앱은? 
. Multi-Featured 
. Multi-Media 
. Multi-CORE 
. Big-Sized 
. Multi-Module 
에서 효율적 + 빠른 개발과 유지 보수 

함수형 프로그래밍 - 간결한 코딩, 이벤트 처리 효율성

안드로이드는 Activity가 메인이자 하나의 앱 단위가 될 수도 있음. 
So library를 로드하면 프로세스를 다시 띄워 죽이지 않는 한 살아 있음
멀티프로세스 지원 필요

아키텍쳐 기반의 접근
Language Tookit 
. Kotlin Tookit 
View-Data 패턴 
. MV. MVC. MVP. MVVM 
State Model. Finite State Machine 
. State Model- 간단한 이벤트로 상태관리 (디바이스) 
. FSM - 이벤트에 따른 상태변화와 동작 구조(프로토콜, 앱상태) 
Media Processing 
. Piped Stream Model 
. Multiplexed Event Queue Model 
모듈화 
. Layed Project
. Dynamic Feature Module

어떤 것을 어떻게 적용할까?
.Kotlin toolkit 
.이벤트 라우팅 필요
.View data model
.Network model
.Multimedia model
 : MQ(센서), Produce-consumer(미디어생성 소비),pipes&filters(실시간 미디어 생성 소비)
.대용량앱 모듈 구조
 : 안드로이드 제공 기술을 사용 가능하나 결국 프로젝트, 모듈, 리소스, 코드를 컴포넌트로 분리하는게 필요함




ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[React, Angular, Vue를 한 번에 지원하기 위한 설계 (Cross Framework Component)]


Cross Framework Component(CFC)
> 하나의 공통 모듈 기반으로 다양한 프레임워크를 지원하기 위해 효과적인 구조를 가진 컴포넌트

Egjs의 바닐라 컴포넌트를 제공하여 다양한 기능을 사용할 수 있게 하였지만 프레임워크에서 사용 시 문제 발생
: 바닐라 컴포넌트가 각 프레임워크에서 동작이 다르거나 프레임워크에서 필요한 기능을 제공하지 않을 수 있음.

프레임워크를 래핑하거나 수정한다면 동작 이상 중복 코드의 문제다 있음 > DOM 조작

DOM diff
.?

CFC 원리
. 컴퍼넌트에서는 data를 삭제해야하지만 프레임워크에서 dom을 삭제하므로 데이터만 삭제 필요.
. 데이터 확인, 동기화?를 위한 listdiffer 를 만듬
. 프레임워크에서는 dom을 삭제 후 listdiffer로 동기화(삭제 > 유지 > 추가)

*자세한 내용은 발표자료*



ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[2019년 FE 프레임워크를 배우는 기분(FE 인싸들이라면 알고 있어야 하는 프레임워크 기술들)]


발표자료를 읽어보자.
발표자료가 정말 인싸의 자료답다~!



ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[Armeria: 어디서나 잘 어울리는 마이크로서비스 프레임워크]



마이크로서비스에 대한 간략한 설명과
만드신 프레임워크의 장점에 대해서 소개하심
함께 slack이나 nhn, kakao에서 적용한 사례를 말씀하심.

2019년 10월 29일 화요일

DEVIEW 2019 Day1 참가 세션 메모

세션에 참가해서 필요한 내용이나 기억에 남길 것을 메모함. 자세한 내용은 발표자료 참고.
솔직히 ML, AI는 뭔소린지 모르겠음.



[외산 클라우드 없이 AI 플랫폼 제공하기: features, training, serving, and AI Suite]


자체 AI 플랫폼 이유
.security - 국내 데이터는 국내에서, 지리, 정부 승인 등
.cost 
.demand

네이버는 사용하던 AI 플랫폼이 있었음
이를 엮어서 > AI Suite : End-to-End AI platform

머신러닝을 위해서
데이터 처리 ㅡ 모델 학습 ㅡ 서빙이 필요함.
실제 개발에서는 
=> 데이터 처리가 오래 걸림, 자동화 고려 필요

AI Feature 안에서
. Dump : 데이터를 가져오고
. Analyze : 가시화를 통한 인사이트
. Batch : 데이터를 선별하여 feature vector생성

Facets
단점 
. 모든 데이터 클라이언트에서 돌리므로 성능 이슈 > 샘플링을 통해서 통계를 보고 인사이트를 얻음
. HDFS라 전체를 다 읽어야 샘플링 가능 > 일부를 읽어서 전체를 예상하고  estimation 하여 샘플링

모델연구시
. 최대 GPU자원 사용
. 동시 사용하여 성능 좋은 모델 선정
. 데이터 고정으로 캐싱하면 이득

하지만 제품화 시
. 최소한의 자원 사용 (비용문제 이유)
. 배포전 이전 모델의과 품질을 검증 필요
. 새로운 데이터로 캐싱 의미 없음

서빙 = APS 서빙 + 모델 서빙

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ




[Papago: Engineering BERT into NMT]


몇가지 적긴 했는데 그냥 발표자료를 참고하여 논문을 찾아 읽어야 할 듯

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


[챗봇 1만 개의 모델 서빙하기: AI 서비스 어디까지 해봤니]


중요한 건 모델의 규모와 서비스 형태 

미신러닝
.수백 수천 토큰 질의를 해하는 모델
. 도메인 전용 학습이 필요하지 않은 모델
.10턴 이상 문맥을 고려하지 않는 모델

구축>훈련>평가>개선 흐름을 자동화
모델의 비용을 계산하고 결과를 봐야함.

Amdahl's law
무한의 컴퓨팅 자원을 투입해도 20%의 속도 개선이 가능함.
아니 경제적인 모델: 학습과 추론의 성능 최적화가 곧 비용인 시대

최적화?
. 모델 최적화
. 모델러와 소통
. Framework customizing, JNI 수준까지
. 확장 CPU Register사용(bert 120ms에서 bert AVX-512 MKL 7ms로 개선)

1만개 서빙?
. AutoML auto quantization
. One source multi environment models(네이버 C3DL 기반 동작)
. Decentralized clusters (kaa) akka, spark, scala, tf


ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


[모바일 얼굴인식, 엔진부터 DEVIEW에 적용하기까지]


얼굴인식으로 인증 단계 감소
1:N의 얼굴 인식의 경우 보조 인증을 주로 사용

Face engine
얼굴 검출 > 특징점 검출 > 얼굴인식 딥러닝
=>Clova Face

얼굴 검출을 위한 모델 얘기는 발표자료 참고
Engine을 Product에 적용하는 얘기도 발표 자료 참고

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



[어디까지 깎아봤니?: 모바일 서비스를 위한 가벼운 이미지 인식/검출 딥러닝 모델 설계]


발표를 들으며 "발표자는 진정 방망이모델 깍는 노인이구나"라는 생각이 머리를 계속 맴돌았음.
발표자료는 꼭 보시길

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


[예약 전화도 쉽게 받는 인공지능 비서를 만드는 P;ㅠ]


이분은 회사에서 자주 본 것 같은데 비슷한 사람이었나?

아직도 전화 예약을 많이 한다.
사람도 전화응대를 잘 못한다.
스피커, 챗봇과는 다름

Conversation Space

Turn, Sequence, Activity,Task 로 대화를 구분

대화에는 실패가 없다. 
Command control 패턴과 같은 스피커에서와는 다르게 대화를 반복하여 해결 가능

Full duplex <> Gateway >ASR >DNNLU >SYNTH >Gateway

성능향상을 위한 모델
. Contextual hint
. Multi turn
. Task moving
. Barge in

엔지니어링 이슈들
. Latency
. Initiative Control