관리자는 직접 코딩하지 않고, 주로 기획과 평가를 담당합니다.

 

기획에 집중하다보면 UI/UX에 대한 체계적인 접근과 명료한 법칙을 고려해야 합니다. 자신의 경험에만 의존하지 말고, 다른 제품과 다른 관점에서 검토하고 장단점을 비교하여 결정해야 합니다. 또한, 조직 규모를 고려하여 개발된 앱을 평가하는 것이 중요합니다. 팀원들의 의견도 적극적으로 수용하여 개발 방향성을 제시해야 합니다.

최근 UX 관련 인터넷 글에서는 토스 앱이 자주 언급됩니다. 실제로 토스 앱은 매우 사용하기 편리합니다. 불편한 부분을 모두 제거하여 깔끔한 앱으로 만들었으며, 알림창, 화면 배치, 안내 및 프로세스도 표준에 맞게 구성되어 있습니다. 게다가 토스 앱은 네이티브 앱으로 개발되어 있어서 화면 전환 등에서 더욱 부드러운 사용감을 제공합니다.
* 앱 개발을 2가지로 나뉠수 있는데, 하이브리드(하나의 소스로 아이폰, 안드로이드 배포)와 네이티브(아이폰 전용 개발, 아니드로이드 전용개발) 이다. 하이브리드앱은 관리 측면, 네이티브는 최적화 측면에서 장단점이 있다.

그럼 존 야블론스키가 저술한 ≪UX/UI의 10가지 심리학 법칙≫에서 소개하는 10가지 UX 법칙을 보면서 왜 토스앱이 정말 잘 만들어진 것인지 뜯어보았다.

< 제이콥의 법칙 : 익숙한 방식 >

사용자가 오래 사용하면서 축적된 경험에 기반하여 새로운 제품을 평가한다는 것을 말합니다. 따라서 기존 방식을 완전히 무시하고 새로운 방식으로 서비스를 제공하거나 리모델링하면 사용자들은 처음부터 다시 학습해야 하기 때문에 불편해하게 됩니다. 금융 서비스 앱인 토스는 익숙한 인터페이스와 사용성을 제공하여 사용자들이 쉽게 적응할 수 있는 것이 그 예시입니다.

< 피츠의 법칙 : 쉬운 터치 >

목표물의 거리와 크기에 따라 목표물에 도달하는 데 걸리는 시간이 달라진다는 것입니다. 따라서 터치할 수 있는 객체 간의 거리는 적당해야 하며, 각 객체의 크기와 흐름도 고려되어야 합니다. 또한 모바일 디바이스에서는 사용자의 시선이 중심부에 집중되므로, 여러 객체 간 리스트를 나열할 때에는 Vertical 형태로 나열하는 것이 좋습니다.

< 테슬러의 법칙 : 불편함을 최소화 >

모든 시스템에는 더 이상 줄일 수 없는 일정 수준의 복잡성이 존재한다. 토스는 사용자가 입력한 계좌번호에서 은행별 계좌번호 고유의 패턴을 파악하여 추천 은행명 버튼을 제공함으로써, 사용자가 일일이 은행을 찾아볼 필요를 줄이고자 합니다. 이를 통해 사용자의 불편함의 간극을 줄이도록 서비스를 제공합니다.

< 힉의 법칙 : 선택지 최소 >

선택지가 너무 많으면 사용자들의 인지 부하가 증가한다는 것입니다. 선택지의 개수가 증가하면 선택 시간이 늘어나고, 사용자들은 스트레스를 받게 됩니다. 따라서 정보를 펼쳐서 보여주는 것보다는 필요한 정보만을 간결하게 제공하는 것이 좋습니다.

< 밀러의 법칙 : 질문 갯수 및 구역(경계) 명확히 >

우리는 작업 기억에 7(+-2)개의 항목만 저장할 수 있다는 것입니다. 따라서 토스에서는 적당한 객체 수와 확실한 경계선을 두어 덩어리화하여 사용자에게 보다 쉽게 정보를 전달하고자 합니다.

< 포스텔의 법칙 : 요청량 최소, 1thing / 1page >

사용자에게 요청하는 정보의 양이 많을수록 인지부하가 증가하고, 피로도가 쌓인다는 것입니다. 이에 따라 토스에서는 "1 thing / 1 page" 철학을 따라 사용자에게 보수적으로 정보를 제공하고, 사용자의 편의성을 고려한 간편한 회원가입 프로세스를 제공합니다.

< 피크엔드의 법칙 : 순간의 실패를 부드럽게~ >

사용자 경험은 오랜 이용을 바탕으로 한 합계가 아니라, 절정의 순간이나 마지막 순간에 느낀 감정이 크게 작용한다. 우리는 앱을 사용하면서 중요했던(기억나는) 순간, 특히 '실패했던 순간'을 더 오래 기억하려는 경향이 있다. 토스는 실패의 순간도 최대한 부드럽게 표현하기 위해 귀여운 애니메이션이나 토스 특유의 친근한 문구를 보여줌으로써 작은 실패로 느껴지도록 불편함을 최소화합니다.

< 심미적 사용성 효과 : 이쁜게 쓰기도 좋다 >

디자인이 아름답다면 사용성도 높아질 것이라는 심리적 효과를 말합니다. 토스의 캐주얼하고 둥글둥글한 인터페이스 디자인은 금융앱이 가지고 있던 딱딱한 이미지와 달리 사용자들에게 더욱 친근하고 쉽게 다가올 수 있도록 도와줍니다.

< 폰 레스토프 효과 : 색다른 것만 기억하는 효과 >

비슷한 여러 객체 중에서 가장 색다른 것만 기억한다는 효과를 말합니다. 이를 활용하여 특정 기능이나 정보를 강조하고자 할 때는 진한 컬러나 보색 컬러를 사용하는 것이 효과적입니다. 처음 서비스에 유입된 사용자에게 길을 알려주거나, 새로운 기능을 소개할 때, 혹은 알림이나 배지를 사용할 때 자주 마주할 수 있습니다. 그러나 시각적 강조를 너무 많이 사용하면 사용자의 집중력을 저하시켜 산만해지게 만들 수 있으니 주의가 필요합니다.

< 도허티 임계 : 딜레이 없는 서비스 >

사용자의 관심을 유지하고 생산성을 높이기 위해서는 0.4초 이내에 시스템 피드백을 제공해야 한다는 원칙입니다. 토스의 경우, 대출 심사 등 외부 정보를 호출하는 구간에서는 귀여운 애니메이션을 제공하여 사용자의 딜레이를 덜 느끼도록 도와줍니다.

채드윅 님의 브런치에서 더 자세한 내용을 확인할 수 있습니다.

토스앱은 사용하면 할수록 대단하다고 생각되는 것이, 직관적이기에 별다른 허들없이 새로운 서비스를 쉽게 경험할 수 있습니다. 그리고 게임요소를 많이 접목하여 계속 접속을 유도하고 있습니다. 최근에는 블루투스를 활용한 '친구와 함께 토스 켜고'를 통해 젊은 사람들 사이에 유행을 하고 있고, 나이드신 분들 사이에서는 건강과 함께 챙기는 '만보기'를 통해 매일매일 40원~100원씩 건강과 재미를 함께 즐기신다고 합니다.

앞으로도 토스앱의 꾸준한 발전을 기대합니다.

 

Posted by 목표를 가지고 달린다
,

Spring Boot 공부하면서, swagger 연동 오류날 경우

org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

이런 에러가 발생했습니다

현제 사용하는 버전은

springboot : 2.6.5
swagger : 3.0.0

Spring boot 2.6버전 이후에 spring.mvc.pathmatch.matching-strategy 값이 ant_apth_matcher에서 path_pattern_parser로 변경되면서 몇몇 라이브러리(swagger포함)에 오류가 발생할 수 있다고 합니다.

[해결방안]
resource폴더안에 application.yml 에 아래 설정을 추가하면 오류가 발생 안합니다.

spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher


Posted by 목표를 가지고 달린다
,

프로프레임은 현재는 AIX 서버에서만 돌아가는 프레임워크다.

실제 정상적인 비즈니스 오류, 디비 오류는 모두 일반적인 ulog 폴더에서 확인 가능하지만,

예상치 못한 오류(참조 오류 등)는 core로 떨어지면서 해당 TP서버는 재기동 된다.

core dump는 log 파일에 생성되지 않아 일반적으로 dbx를 사용해서 확인해야 하는데, 확인하기가 쉽지 않다. 

일반적으로 core 파일은 core를 발생시킨 바이너리와 동일한 폴더에 생성되지만 프로프레임은 보통 $PFM_CORE_DIR/{코어발생날짜}/{코어발생모듈} 폴더에 core 파일을 생성한다. ( 보통 ulog와 동일한 위치에 존재)


file 명령어를 사용하면 core 가 발생한 프로그램 바이너리와 bit 수를 출력해준다.

pfm5c@tmax:/pfm5c/proframe/logging/core/20181026/STEST00004]file core
core: AIX core file 64-bit, TPFM01(서버명 또는 서비스명)

dbx 명령어로 프로그램 바이너리 경로와 core 파일을 실행한다. 위의 코어는 티맥스 tcs 서버에서 호출한 서비스 모듈에서 발생한 core 이므로 서버 바이너리 경로는 $TMAXDIR/appbin 밑에 있는 서버 바이너리를 넣어준다.

ex> dbx [바이너리경로] [코어파일명]

pfm5c@tmax:/pfm5c/proframe/logging/core/20181026/STEST00004]dbx $TMAXDIR/appbin/TPFM01 core

경고: 코어 파일이 전체 코어(fullcore)가 아닙니다. 일부 정보가 사용 가능하지 않을 수 있습니다.

[core에서 메모리 이미지 사용]

기호 정보를 읽는 중 ...

Segmentation fault in pfmKillSelfProcess at line 1056 in file ""

"pfmOsWrapper.c"을(를) 읽을 수 없습니다.

(dbx)

dbx는 많은 명령어와 다양한 분석기법 사용이 가능하지만 가장 간단하고 흔히 쓰는 명령어는 [ where ] 명령어다. where 명령어로 function call stack을 읽어서 어떤 파일의 어떤 function이 호출될 때 core가 발생했는지 확인이 가능하다.

결론적으로, core 파일이 저장된 폴더로 가서 [dbx $TMAXDIR/appbin/TPFM01(서버 또는 서비스명) core ] 를 친 후, [ where ] 검색을 통해 참조 과정에서 오류나는 것을 찾으면 된다. 

통상 자주 발생하는 core는 PFM_ERR, PFM_DBG, PMF_LOG 시 문자열을 출력하는데, [%ld]를 사용하거나, 숫자를 출력하는데, [%s]를 사용하는 등 자료형을 잘못 이용할 때 발생한다. 

Posted by 목표를 가지고 달린다
,

Margin과 Padding의 차이

마진과 패딩의 정의

Margin(마진) : 테두리를 기준으로 바깥부분에 차지하는 영역
Padding(패딩): 테두리를 기준으로 안쪽에 차지하는 영역

Margin과 Padding은 보통 테이블을 작성할 때, View 객체들이 테이블 표테두리에 바짝 붙지 않고, 약간의 공백을 두기 위한 것으로, layout 을 정의할 때 layout_marginTop, layout_marginBottom등 특정면에만 공백을 줄 수 있고, layout_margin, layout_padding 으로 전체4면을 한꺼번에 줄 수도 있다.

안드로이드의 margin의 최소(기본)값은 8dp이며, 구글은 8의 배수(16, 24, ..)로 주는 것을 권고한다.

Posted by 목표를 가지고 달린다
,

코딩의 진정한 고수란 누구인가?

 

IT개발자가 일을 잘 한다는 것은 무엇일까?

국가 정보시스템 감리에서는 사업(일)을 할 때,

기능성(내용이 충분하고 완전함), 무결성(내용이 정확함), 편의성(이해 및 활용의 편의), 안정성(테스트 결과서), 보안성, 효율성(성능향상), 준거성, 일괄성을 요구한다.

쓸데 없이 기교를 부리거나, 도전의식으로 새로운 것(익숙치 않거나 이용하기 어려운 라이브러리 등)을 행하는 것은 업무에 중요하지 않다.

개발을 할때, 업무 요건와 프로세스를 단순화하여 개발 및 유지보수가 용이하게 설계한 후,
적절하게 DB의 SQL문과 AP의 Coding에서 기능을 구현하는 것이 개발자의 능력의 척도이다.

어줍잖은 실력으로 오라클의 통계함수나 rollup, cube 등을 쓰는 것보다 때로는 union 으로 2번 읽는 것이 유지보수가 쉽고 남들도 해당 업무 파악이 쉬울 수도 있다.(물론 약간의 성능저하는 있을 수 있으나, 거래가 많지 않다면 무시)

그렇다고 무식하게 코딩하라는 것이 아니다.

적절하게 기술을 발휘하라는 말이다.

 

 

Posted by 목표를 가지고 달린다
,

DB관련 유용한 사이트 모음


모든 문제 해결은 누군가에게 물어보기 보다는, 직접 찾아보고 해결책을 강구하는 것이 좋으며, 문제 해결은 이슈해결과 더불어 향후 재발방지를 위한 조치까지 확인해야 한다.
개발자라 하더라도, DB는 시스템 부분과 DB 아키텍쳐까지 이해해야 성능(튜닝)부터 운영까지 효율적으로 설계할 수 있으니, 틈틈히 보거나 문제 생겼을 때, 운영유지보수팀에 문의하면서 같이 고민해 보길 바란다.

[ORACLE]

prodba 네이버 카페 | DBMS 전반
https://cafe.naver.com/prodba

dbian 네이버 카페 | 튜닝
https://cafe.naver.com/dbian

조동욱님 블로그 | DBMS 전반
http://ukja.tistory.com

유건데이타 자료실 | DBMS 전반
http://dbtech.co.kr/bbs/?bo_c=10

구루비 | DBMS 전반
http://www.gurubee.net/

구루비 스터디 | DBMS 전반
http://wiki.gurubee.net/dashboard.action

아무도없는세계님 블로그 | DBMS 전반
http://dinggur.tistory.com

BlueOne | DB사업팀 | DBMS 전반
http://otsteam.tistory.com

DBWORKS_oracle | DBMS 전반
http://support.dbworks.co.kr/index.php?mid=ora_tb

투씨에스지 기술블로그 | DBMS 전반
http://tocsg.tistory.com/

굿어스 DB기술노트 | DBMS 전반
http://blog.goodus.com/category/Good%20Tech

DBA의 정석 | DBMS 전반
http://haisins.epac.to/

내맘대로 긍정 | DBMS 전반
http://positivemh.tistory.com/

데이터포럼 | 설치 가이드
http://dataforum.kr/display/INSTALL

Posted by 목표를 가지고 달린다
,

Head First 시리즈는 "생각하게 만드는 책"이다. 요즘 인터넷이 발달하고 많은 자료, 샘플 자료들이 널려 있기에 검색해서 사용하면 느리지만 가능하다. 기술은 없으나 기교를 키울 수 있다.

하지만, 본 시리즈는 개발자에게 왜 이렇게 구동하는지? 이렇게 하면 어떤 이익과 문제점이 있는지를 잘 구분해서 알려준다. 기술서적이라기 보다는 산책하는 기분으로 읽기에 1주일 이내에 빠르게 봐야 의미가 있다.

해당 시리즈는 여러권 읽어 보았으나, 오늘은 Ajax에 대해 쓰기로 한다.

Ajax는 java script를 활용하여 DOM, JSON, XML을 활용하는 기법이다.

즉 특별한 기법이라기 보다는 특화(?)된 기법이라고 하는게 맞다. 이책 Head First 특성상 디테일한 내용보다는 개념을 잡는 책이다.

기존 JavaScipt 를 사용해본 사람이면, 예를 들어

<html>

<Head>

<script language="javascript">

 function example() {

      var dev1 = "1";

      dev2      = "2";

       .........

      }

</script>

<body onload = example();>

이런식으로 활용했을 것이다.

최초 화면 로딩시 특정 함수를 실행하는 방법은 2가지이다.

1. 위의 예제처럼 body 태그안에 onload= "함수"를 명시.

2. 스크립트 정의하는 부분에

window.onload = example;

이라고 ()를 제외한 함수를 명시하는 것이다.

 

3. 변수 역시 var를 사용하지 않으면 해당 변수는 전역변수로 인식한다. 그래서 대부분 사용자가 함수정의시에 var를 사용해서

다른 함수와 변수가 겹치지 않도록 지역변수로 선언한 것이다. 이것 역시 funtion example() { .........} 구분 밖에서 선언하면,

var를 사용해서 선언하였다 하더라도 { } 밖에서 선언한 것이라 전역변수가 된다.

이것은 추후에 함수 사용시 변수를 재사용할 수 있는 여부를 결정짓기 때문에 중요하다.

# 예제 소스

function checkUsername() {

request = createRequest();

if(request == null )

alert("unable to create request");

} else {

var theName = document.getElementById("username").value;

var username = escape(theName); <----- 특수문자들을 처리하기 위해서 escape 함수로 변수 처리

var url = "checkName.php?username=" + username;

request.onreadystatechange = userNameChecked; <-----결과가 나오면 처리할 함수를 설정

request.open("GET", url , true); <-----get, post방식, url, true(비동기), false(동기) 방식.

request.send(null);

}

 

# 예제 소스

- 보여지는 부분과 기능을 구현하는 것을 구분하는 방법은 CSS를 활용하여 보여지는 것을 구분하는 것이다. 즉 클래스를 설정한 후,

자바스크립트로는 클래스를 변경해주면 된다.

CSS 파일...

#username {

background : #ff url .....

}

#username.checking { background :...}

#username.approved { backgroudn...}

 

# 예제소스

- 엘리먼트 찾기 : 엘리먼트들은 일종의 parent-child 관계이기 때문에 특정 element를 찾은 후, 다시 거기서 element검색이 가능하다.

function showTab() {

var selectedTab = this.title;

var images =

document.getElementById("tabs").getElementsByTagName("img"); <--- 특정 Element 안에 Element로 검색

for(var i =0 ; i < images.length; i++){

var currentImage = images[i];

}

}

# 예제소스

2개이상의 이벤트 등록하기

- 사파리, 파이어폭스,

currentBtn.addEventListener("mouseover", showHint, false);

currentBtn.addEventListener("mouseover", buttonOver, false);

- IE

currentBtn.attachEvent("onmouseover", showHint);

currentBtn.attachEvent("onmouseover", buttonOver);

- 1개만 등록시에는

currentBtn.onclick = showHint;

- 이벤트 제거방법

currentBtn.onclick = "";

 

# 예제소스

- this 가져오기.

브라우져마다 this를 가져오는 방식이 다르다. 위의 showTab() 에서 this를 해결해주는 방법.

function getActivatedObejct(e) {
var obj;
if(!e) {
//early version of IE
obj = window.event.srcElement;
} else if(e.srcElement) {
// IE 7 이상.
obj = e.srcElement;
} else {
// DOM Level 2 Browser
obj = e.target;
}
return obj;
}

 

# 1장의 전체 소스

붙임파일 참조.

if(passwordRequest.readyState == 4) { << -- 비동기전송의 결과가 옴.

if(passwordRequest.status == 200) { << -- 처리가 정상으로 됨.
if(passwordRequest.responseText == "okay") { << --결과값을 검증.

 

# 함수소개

1. t = setInterval(scrollImages, 50); (함수, 밀리초단위시간) << - 주기적으로 함수를 실행함.

2. var pieces = "Decide, Commit, Succeed".split(",");

alert(pieces[0] + "," +pieces[1] + "," +pieces[2] );

3. insertBefore(), appendChild()와는 달리 특정 엘리먼트 앞에 추가함.

4. removeChild()는 노드를 제거하는데, 마지막 노드부터 제거해야 함.

 

# DOM특징

모든 노드들은 parentNode라는 속성을 가지지만 parentNode 속성은 읽기 전용.

appendChild() 함수. --> Node.appendChild(element);

노드 관련 속성 : parentNode, firstChild, lastChild, childNodes, nextSibling, previousSibling, nodeName

이중에서 nodeName에 관하여...

엘리먼트 노드들은 엘리먼트 이름과 동일한 노드 이름을 지니고, 문자 노드의 노드이름은 "#text"이다.

즉 img 경우 nodeName은 img 이지만, 문자열은 "#text"이다.

 

# 프레임워크

$("username") 문법은 document.getElementById("username"); 을 의미함.

9장에서는 요청과 응답으로 데이터를 주고 받을 때 사용하는 방식에 대해 설명한다.

1. XML 2. JSON 3. innerHTML

 

# JSON 객체의 멤버에 접근하는 예제

for ( var property in hero ) {

alert("Found a property named : " + property);

}

 

# 예제소스 참조 XML 파싱

# 예제소스 참조 XML 파싱에서 어레이와 단순속성 파악후 처리.

# 예제소스 참조 JSON 파싱

# 예제소스 참조... property의 속성을 확인하여, 어레이와 단순속성을 확인하여 처리.

 

 

# 서버의 응답은 바로 실행하는 것보다는 분리해서 실행하는 것이 안전.

-> var itemDetails = JSON.parse(request.responseText);

JSON은 json2.js라 로드 될때 생성되며, parse는 문자열이 JSON형태면 객체를 반환.

 

# 예제소스 참조 안전한 방법 POST

registerRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

헤더 설정 필수, get 방식은 url전체를 보내는 것이라 설정할 필요가 없으나, post방식은 명시해줘야 함.

 

# 유명한 library ( framework)

1. script.acluo.us

2. yahoo ui (YUI)

3. prototype

4. jQuery

5. mooTools

Head+First+1장소스.js.js
0.00MB
Head+First+2장소스.js.js
0.01MB
util(Head+First).js.js
0.00MB

예전에는 JavaScript에 대해 다양한 기술이 난무하여 표준이 없었으나, 산업이 발전하다 보니 표준기술보다는 산업의 기술(구굴, 페이스북 등)에서 프레임워크로 Ajax보다 뛰어난 것들이 많이 나오고 있다. 모든 것은 기본이 충실하면 이해가 쉬우니 느리더라도 단계를 밟아 가길 바라며, 바쁘다면 열심히 읽기 바란다.

 

Posted by 목표를 가지고 달린다
,

금융권 종사자는 필수, 일부 행정관련 업무 관련 IT업무 담당자는 반드시 알아야 하는 검증식.

 

금융거래실명법에 의거하여, 금융거래는 "주민등록번호", "외국인등록번호", "여권조합번호"로 거래를 할 수 있다.

 

해당 실명번호가 맞는지를 IT담당자는 체크할 필요가 있어서 붙이며,

 

실제 실명번호에 130229-******* 등.. 잘못된 생년월일이나, 잘못된 체크디짓으로 부여된 번호가 있을 수도 있으므로,

어느정도로 적용할지를 반드시 이용자(기획자)와 협의 후....적용

 

예) 891230-1234560

주민등록번호를 2부터9까지 다시 2부터 5까지 올림차순으로 곱해서 더한다.

8x2+9x3+1x4+2x5+3x7+0x8+1x9+2x2+3x3+4x4+5x5=141

더한값을 11로 나눈다.(12.8)-소수첫째 자리까지 반올림

소수첫째자리 숫자에 10을 더해서 11이 되면 OK(외국인등록번호는 13)

소숫점 없이 11로 나누어 떨어져도 OK

 

내국인 주민등록번호 검증 엑셀 수식

=IF(RIGHT(C7,1)=(RIGHT(11-MOD(MID(C7,1,1)*2+MID(C7,2,1)*3+MID(C7,3,1)*4+MID(C7,4,1)*5+MID(C7,5,1)*6+MID(C7,6,1)*7+MID(C7,7,1)*8+MID(C7,8,1)*9+MID(C7,9,1)*2+MID(C7,10,1)*3+MID(C7,11,1)*4+MID(C7,12,1)*5,11),1)),"O","X")

 

외국인 등록번호 검증 엑셀 수식

=IF(RIGHT(C7,1)=(RIGHT(13-MOD(MID(C7,1,1)*2+MID(C7,2,1)*3+MID(C7,3,1)*4+MID(C7,4,1)*5+MID(C7,5,1)*6+MID(C7,6,1)*7+MID(C7,7,1)*8+MID(C7,8,1)*9+MID(C7,9,1)*2+MID(C7,10,1)*3+MID(C7,11,1)*4+MID(C7,12,1)*5,13),3)),"O","X")

 

Posted by 목표를 가지고 달린다
,