올해 목표가 슈퍼 란도너라..


과정 중에 있는 서울 400 코스를 다녀왔습니다.


코스중

대부도로 가는 방파제? 바다길? 은 정말 일품입니다. (바람 빼구요 ... 바람 ㅠㅠㅠ.. 휘청휘청.. )


란도너 특성상 다른 그룹과도 많이 라이딩하게되는데

선두에 계시던 분이 오이도 사주시고.

밥도 같이 먹고 했네요( Team Boodoo 감사합니다! )



27시간의 컷오프를 가진지라.

잠 안자고 달리기를 감행했는데

5월의 저녁은 아직 많이 춥습니다.

긴빕, 긴팔, 바막 챙겨입었는데

저녁에는 추워서 달릴수가 없더라구요 새벽내 라이딩했는데

30분 단위로 편의점들어가서 몸 녹이고 발녹이고 30분타고 -> 반복 ;;;


해떨어지고나면 -_- 아무것도 안보입니다... 경치고 강이고 저수지고. 

그냥 지도 옆에 뭐가 있내하면 있는가 보다 하면서 도로만 보고 달리게됩니다...



해뜰무렵 서울에 도달하여서는 잠과의 싸움이었습니다..

종료까지 20여 km남았는데.. 도저히 안될거같아 마지막 파워젤을 먹고 22시간 8분에 완주하였습니다.

평지 복귀를 위해 파워젤을.. (솔로잉이었는데!!) 빨줄은 생각도 못했네요 ..


귀가하고 샤워하고 눈뜨니

온몸이 다 아프네요 .. 팔꿈치, 무릎 내측  허리 어깨....

지금 예상하기로는

무릎내측은 클릿 각도 문제

팔꿈치, 허리 어깨는 척추기립근 부족으로 인한 통증.. 으로 예상중입니다.. 유연성 부족도 한몫하겠네요..


3주후에 있을 600을 대비해서 미리 준비좀 해야겠습니다.





사용중인 갤럭시 S3 의 개발자 도구가 환경설정에서 사라졌다..


숨김 처리가 되있는 ...


서두는 짧게.


홈화면 -> 메뉴버튼 -> 환경설정 -> 더보기


-> 디바이스 정보 

-> 빌드번호를 터치터치터치... 연속으로 하다보면.   3 2 1 . 하고 떨어지면서 Toast가 노출된다...


개발자도구가 활성화 되었습니다.. 라는 문구가 나오고 


Back 버튼... 


더보기 메뉴 아래에  개발자 도구가 활성화 되어있다..


우야건 Success...






최근 자전거 타는 시간이 극도로 늘어나면서 


사고사례도 많이 접하게 되고 겸사겸사 지인을 통해 키캠을 구입하게되었습니다.


목적은 단하나. 블랙박스..


사고 발생시 나를 증명해줄 유일한(?) 수단중 하나이기에 오늘 야간 라이딩 테스트를 진행하였습니다..


손가락 두개만한 이녀석이 과연 잘 보여줄까...


... 두둥...







망했............


그렇다면 밝기를 올리면 어떨까?




보.. 보인다!!!








라이딩중에 전조등을 항시 키고 있었음에도 불구하고.. -_- 칠흙같은 어둠이 깔리는 곳에는 까만색만 녹화가 됩니다.


허나 .. 동영상 플레이어의 밝기를 올리면 사물의 구분이 가능해집니다.


고로 블박으로서 역할 수행이 가능해진다라는 점입니다.



배터리가 40여분뿐이 안가지만 외장 배터리를 이용해서 마구마구 녹화가 가능한점

저렴한 가격... ...


가격때문에 모든게 용서가됩니다 ( ..)



이상 백년만의 포스팅 끝...



페이스북 생활코딩 그룹에 나온문제중 하나...

https://www.facebook.com/groups/codingeverybody/



"1원, 5원, 10원, 50원, 100원, 500원짜리가 각각 C1, C5, C10, C50, C100, C500개씩 있습니다. 가능한 적은 수의 동적으로 A원을 지불하려면, 몇 개의 동전이 있어야 할까요? 지불 방법은 적어도 1개는 존재한다고 가정합니다."




자바 개발자로서(?) 


낼름 풀어보았다...


public static void main(String[] args) {

int val = 5323; // 입력값


int cv = 1000; // 500 -> 100 -> 50 으로 변할값.

int cx = 0, div = 0; // cx는 동전의 갯수 div는 2 : 5 스위치 값.

do {

div = (div == 2 ? 5 : 2); // 처음에 div 는 0이므로 div는 2가 되고 

cv = cv / div; // cv는 500이된다.

cx += val / cv; // val / cv 는 정수값이므로, cx에 나누기의 몫이 들어가고

val = val % cv; // 나머지 값은 다음턴으로 넘긴다.

} while (cv != 1);    // 1이 아니면 루프... do 아래 2번재 줄에서 cv 가 1이되어도 연산이 되므로 문제가 없다.

System.out.println(cx); // 대상 목적인 코인의 갯수만 출력 >.<.

}


댓글로 작성된 다른 능력자 분들의 코드를 보고 있자니..

아직 멀었구나 하는 생각만든다..( 파이썬 능력자님들 ㅎㄷㄷ  , 스칼라도 배우고 싶다능 ... )

좋아하는것을 하나하나 쌓아가는 2013년이 되었으면 하는 바램으로 간만의 포스팅 끗..

상황 : Spring기반으로 짜여진 서버에서 한 클래스의 데이터를 모니터링 페이지에 띄우고자 합니다.


출력해야하는 클래스는 들고 있는 데이터의 가지수만 최소 5-7개에서 내부필드는 20-30개까지


하나하나 정성스레 포멧팅 해주면 되지만. 귀차니즘이 앞서서 어찌하면 이쁘게 String으로 뽑아낼수 있을까 하여


방법을 찾아보았습니다.








Q : 특정 클래스 A를 Json Format을 가지는 String Type로 출력하고자 합니다.


A.

- 구글에서 제공 하고 있는 GSON Library의 Pretty Format 메소드를 활용하여 출력.


GOOGLE GSON : http://code.google.com/p/google-gson/



#. Test Case

ObjClass.java

 import java.util.ArrayList;

public class ObjClass {
    String name;
    int age;
    String address;
    
    ArrayList<String> newArr;
    
}


Main.java 

 import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
    public static void main(String[] args){
        ObjClass oc = new ObjClass();
        oc.address = "123";
        oc.age = 56;
        oc.name ="myname";
        oc.newArr = new ArrayList<String>();
        
        
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String jsonOutput = gson.toJson(oc);

        System.out.println(jsonOutput);
    }
}


#.Output 

{
  "name": "myname",
  "age": 56,
  "address": "123",
  "newArr": []
}
 




필드의 값이 Null 일 경우에는 아에 출력에서 제외됩니다.





이어서 -


View 딴에 데이터를 전달해서 출력할 계획이기에


Javascript를 이용해서 Json Format에 Hightlight 해주는걸 찾아봐야겠습니다...



파일에서 문자열을 찾습니다.


FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P]

         [/F:파일][/C:문자열] [/G:파일] [/D:디렉터리 목록] [/A:색 속성] [/OFF[LINE]]

         문자열 [[드라이브:][경로]파일이름[ ...]]


  /B         패턴이 행의 첫 부분에 있는지를 비교합니다.

  /E         패턴이 행의 끝부분에 있는지를 비교합니다.

  /L         찾는 문자열을 글자 그대로 사용합니다.

  /R         찾는 문자열을 정규식으로 사용합니다.

  /S         현재 디렉터리와 모든 하위 디렉터리에서 일치하는 파일을 찾습니다.

  /I         찾을 때 대/소문자를 구별하지 않습니다.

  /X         정확히 일치하는 줄만 보여줍니다.

  /V         일치하는 텍스트가 없는 줄만 보여줍니다.

  /N         일치하는 각 줄 앞에 줄 번호를 보여줍니다.

  /M         파일에 일치하는 텍스트가 있으면 파일 이름만 보여줍니다.

  /O         일치하는 각 줄 앞에 문자 오프셋을 보여줍니다.

  /P         인쇄할 수 없는 텍스트가 포함된 파일은 건너뜁니다.

  /OFF[LINE] 오프라인 속성 세트 파일을 건너뛰지 않습니다.

  /A:속성    색 속성을 두 자리 16진수로 지정합니다. "color /?"를 참조하십시오.

  /F:파일    지정된 파일에서 파일 목록을 읽습니다('/'는 콘솔에 해당됩니다).

  /C:문자열  지정된 텍스트를 글자 그대로 찾는 문자열로 사용합니다.

  /G:파일    지정된 파일로부터 찾는 텍스트를 받습니다('/'는 콘솔에 해당됩니다).

  /D:디렉터리    디렉터리 목록을 구분하는 세미콜론(;)를 찾습니다.

  문자열     찾을 텍스트.

  [드라이브:][경로]파일이름

             찾을 파일을 지정합니다.


/C 옵션을 사용한 경우가 아니면, 찾는 문자열을 여러 개 지정할 때

공백으로 분리하십시오. 예를 들면, 'FINDSTR "hello there" x.y' 명령을

입력하면 파일 x.y에서 "hello"나 "there"을 찾습니다.

반면에 'FINDSTR /C:"hello there" x.y' 명령을 입력하면 파일 x.y에서

"hello there"을 찾습니다.


정규식에 대한 참고 사항:

  .         와일드카드: 모든 문자

  *         반복: 문자나 클래스에 대하여 0번 이상 반복

  ^         행 위치: 행의 앞부분

  $         행 위치: 행의 끝부분

  [클래스]  문자 클래스: 세트에 있는 문자

  [^클래스] 역 클래스: 세트에 없는 문자

  [x-y]     범위: 특정 범위에 있는 문자

  \x        이스케이프: 메타 문자 x를 문자 그대로 사용

  \<xyz     단어 위치: 단어의 앞부분

  xyz\>     단어 위치: 단어의 끝부분


Findstr에서 사용 가능한 정규식은 온라인 명령을 참조하십시오.



소스내에서 이 문자열은 어디에 있나? 를 찾을용도로 검색해보고(??) 찾아내고(!!!!!!!!) 기록(?!?!?!?!?)합니다


자세한 옵션은 위 Help 구문으로 대처합니다...



예제1.


현재 폴더 아래의 *.java에 대해서 Controller 라는 문구를 검색


findstr /s "Controller" *.java



예제2.


현재 폴더에서만 *.m 파일 내부의 NSString 을 검색


findstr "NSString" *.m












링ㅋ : http://www.hanb.co.kr/book/look.html?isbn=978-89-7914-962-3


나를 향한 수만번의 채찍질을 감행하게되는 게기가 되었습니다.


책을 읽는 내내 읽혀지지도 않고, 읽혀지더라도 생각할 꺼리가 많습니다.




평소에도 기술서적과 한발쯤은 떨어져있는 내용의 책등은 종종 사서 읽는 편입니다.


소설류나 있고, "프로그래머로 사는법" 같은 자기개발서(?????) 류의 책같은 것들이요..




최근에 읽은 책중에


위 소개한 책과 유사한


http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8997924001


"프로그래머로 산다는 것" 이라는 책을 읽었습니다.



국내 서적이고, 아는 분이 책 속에 주인공으로(?) 등장하셔서 너무너무 즐겁게 읽었습니다. 

( "저 책때문에 내 책이 안팔려!!"라고 하셧다는 소문이 있습니다... 사실 여부는 저도 잘 .. 루머입니다!! 루머!! )


한국에서 개발자로 살아가야한다는것에 대해 채찍과 당근을 조근조근히 받아들일 수 있는 계기 였으니깐요..





다시 본점으로 돌아와서.. 


"프로그래머로 사는 법" 이라는 책을 보고 나서... 나는 잘하고 있는 걸까? 라는 생각이 수도 없이 다가옵니다..


아웃라이어 - "1만 시간의 법칙" 에 대해서 .. 딱 1만 시간이 지나있는 때의 경력인데 ...


과연 나는 전문가가 되어있는가... 혹은. 1만 시간이 지나도 한참이 지났는데.. 난 과연 1만 시간의 투자를 하였는가? ...



내 전공에 대해서.


열정적인가.


노력하는가


전파하는가



하루를 놓고


얼마의 시간을 놀고 얼마의 시간을 일을 하는가



동료에 대해서


멘토와 멘티의 롤 수행은 잘 하고 있는가


나는 독재자가 아닌가




책의 내용 자체는 굉장히 건전하고 건설적이며  흥미 + 노력 = 성공으로 다가가기는 길 이라는 소소한 공식역시도 취할 수 있는 좋은 내용으로 가득합니다.




개발 생활하면서 "이만하면 됐지!"라는 생각과 "난 아직 멀었어!"생각을 약간은 가지고 있었는데


후자에 좀 더 화이팅을 외치면서 2013을 채워 나가야겠습니다.




개발자로 뛰어들려는 분들과 현직 개발자 분들에게 매우매우 강추드립니다.





SQLGate 2010 사용중에 알수 없이 Ctrl이 눌린 현상이 종종 발생합니다.


아래 두 폴더의 내용을 지우면 복구가 됩니다...


C:\Program Files (x86)\SQLGate\SQLGate2010 for MySQL Developer\bin\Form

C:\Program Files (x86)\SQLGate\SQLGate2010 for MySQL Developer\bin\Screen


출처 : 과거 SQLGate에서 검색해서 찾았음..(지금은 기억속에서 ..)




요즘 이클립스에서 이것저것 NodeJS 학습을 진행중인데


개발 경력 얼마나 되었다고 벌써부터 Code Assist 없으면 개발하기 힘들어집니다... (것보담 타이핑 하기 귀찮아 진다? ... 일이라면 하는데 -_- 공부라 생각하니 더 치기 싫어지는 이유는 뭘까  ..요? )


잡설은 여기까지 줄이겠습니다.


---------------


Eclipse에서 NodeJS를 이용하여 개발하는데 Code Assist 사용하기




준비

1. Eclipse

2. NodeJS

3. Git


시작


1. 

Eclipse -> Menu -> Help -> Install New Software -> 


http://download.eclipse.org/vjet/updates-nightly/


위 URL을 추가하여 플러그인을 설치합니다.


2. https://github.com/ebayopensource/vjet-typelib


Git을 이용하여 위 URL을 다운받습니다..

프로젝트를 첨부하고나면

금일 기준 15개 전후의 프로젝트가 첨부가 됩니다.

프로젝트 명중 TL로 끝나는 애들이 앞으로 Code Assist를 담당하게될 Type Libarary가 됩니다.

프로젝트명 Ex : 




마우스 우클릭 -> Import Projects 이후

필요한 것만 선택하여 Project로 가져옵니다.


3. 2에서 첨부된 프로젝트에서 우클릭 Vjet -> Enable VJET Project Capabilities 를 선택하여 VJET 환경 설정을 활성화 해줍니다.

3-1. 첨부한 프로젝트 만큼 반복해주면 됩니다 ( 노가다 만쉐이~~~ )

4. 개발할 JS 프로젝트 (Node JS 프로젝트역시 동일) 생성이후
 
프로젝트에서 우클릭 -> Properties -> VJET -> VJET Build Path -> Project 탭에 추가된 TL 프로젝트를 추가합니다.



5. 이 작업까지 완료하고 나면

js 파일 내에서 첨부된 TL 항목에 대해서만 Code Assist가 동작하는것을 확인할 수 있습니다 ( 유후~ 만세 만세 ;; )





이래저래 검색해봐도 국문으로 작성된 내용은 확인이 되질 않아 초급개발자분들에게 도움이 되고자 

즐거운 개발에 도움이 되고자 (부족한 내용이지만) 글을 적어보았습니다.



#. 주의 사항?


Github에서 확인해보면 최종 Pushed 된 날짜가 2년전입니다.. (2011 04 ~ 2011 05 가 마지막 업데이트입니다 ( ..) )


Node나 JQuery의 경우 광속 Version Up을 하고 있는데 그 빠름을 따라가지 못하는 듯하여


최신 버전관련된 내용이 노출되지않거나 Deprecated된 내용이 정상적으로 노출될수 있으니 100% 신뢰는 금물입니다.





참조 : http://wiki.eclipse.org/VJET/Importing_VJET_JavaScript_Type_Libraries


Win7에서 Node 개발 환경을 구축하고 개발하다가 Custom Module의 추가가 요구되어 질때가 있다.


npm install 블라블라 


명령어를 이용해서 설치하는 방법이 있지만.


설치를 해도 잡히지가 않고


NODE_HOME 환경변수를 등록해도 이클립스에서 모듈을 못불러온다... 


추가로 


www.nodejs.org  에서 Download를 이용해서 받으면


설치 경로 변경도 못한다.!!! ... (윈도우가 설치된 드라이브는 Win7기준으로 이래저래 제한사항이 몇 걸린다... )


그래서 발견한 해결책... 


http://code.google.com/p/nodejs-win/


Node 설치경로 변경가능


기본 모듈 10여개 미리 설치됨


해당 결로의 루트에서 npm install 명령으로 추가 모듈 설치시 정상적으로


동작 :)




개발을 진행하다보면 Apache - Tomcat 구조로 서버 세팅을 완료하고


이미지를 캐싱한다는 이야기를 들었다..


어찌하나 직접 찾아보기로 해서 직접 아파치 설치를 해서 구현해 보았다..



Apache 설치

http://httpd.apache.org/download.cgi#apache24


Windows 기반으로 설치 진행

2.0.64버전을 설치




아파치 설치 경로\Apache2\conf

httpd.conf  : section 2


 LoadModule expires_module modules/mod_expires.so


위 라인 주석제거



httpd.conf Section2 에 아래 항목 추가


 #

# Apache Server Static Data Caching

#

<IfModule mod_expires.c>

        ExpiresActive On

ExpiresByType image/png "access plus 1 month"

</IfModule>



위 설정까지 적용한후 아파치 Restart를 수행한다.



Test용 이미지 등록

C:\Program Files (x86)\Apache Group\Apache2\htdocs\testProject\resources\images\k.png


Test용 Html 등록

C:\Program Files (x86)\Apache Group\Apache2\htdocs\testProject\a.html


a.html 의 내용은 Test이미지를 화면에 노출하는 단순 구조


이 테스트를 위해서 Fiddler를 사용해서 캐싱되는것을 확인하였다.

http://www.fiddler2.com/fiddler2/




아파치 뒤의 서블릿 컨테이너(톰캣)으로 전달되는것을 방지하기 위해


mod_proxy를 손봐야한다는 정보도 Get하였다.



참고 링크

http://ant103.egloos.com/198165

http://www.javajigi.net/pages/viewpage.action?pageId=287244298

http://system.neulwon.com/xe/?mid=linux_apache&page=2&document_srl=1518



안드로이드 에서 메시지 기반으로 이리저리 통통 기기 제어를 하려 하는데....


Permission Deny 상황이 자꾸 떨어진다.


뭘까 ...


http://www.android-permissions.org/permissionmap.html


오늘 (2012 10 09 ) 까지는 잘 접속되는데 나중에 될진 모르겠다..


중한 내용은 아래 내용... Broadcast Message 로 아래 내역은 허락되지 않는다. 시스템딴에서만 전송 가능하다는 이야기.. 다른 방법으로 메시지 날리는게 정답인듯?!?!?


android.app.action.ENTER_CAR_MODE, android.app.action.ENTER_DESK_MODE, android.app.action.EXIT_CAR_MODE, android.app.action.EXIT_DESK_MODE, android.backup.intent.CLEAR, android.backup.intent.INIT, android.backup.intent.RUN, android.bluetooth.adapter.action.DISCOVERY_FINISHED, android.bluetooth.adapter.action.DISCOVERY_STARTED, android.bluetooth.adapter.action.LOCAL_NAME_CHANGED, android.bluetooth.adapter.action.SCAN_MODE_CHANGED, android.bluetooth.adapter.action.STATE_CHANGED, android.bluetooth.device.action.ACL_CONNECTED, android.bluetooth.device.action.ACL_DISCONNECTED, android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED, android.bluetooth.device.action.BOND_STATE_CHANGED, android.bluetooth.device.action.CLASS_CHANGED, android.bluetooth.device.action.DISAPPEARED, android.bluetooth.device.action.FOUND, android.bluetooth.device.action.NAME_CHANGED, android.bluetooth.device.action.NAME_FAILED, android.bluetooth.device.action.PAIRING_CANCEL, android.bluetooth.device.action.PAIRING_REQUEST, android.intent.action.ACTION_MDN_STATE_CHANGED, android.intent.action.ACTION_POWER_CONNECTED, android.intent.action.ACTION_POWER_DISCONNECTED, android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, android.intent.action.ACTION_SHUTDOWN, android.intent.action.ANY_DATA_STATE, android.intent.action.BATTERY_CHANGED, android.intent.action.BATTERY_LOW, android.intent.action.BATTERY_OKAY, android.intent.action.BOOT_COMPLETED, android.intent.action.CONFIGURATION_CHANGED, android.intent.action.DATA_CONNECTION_FAILED, android.intent.action.DEVICE_STORAGE_LOW, android.intent.action.DEVICE_STORAGE_OK, android.intent.action.DOCK_EVENT, android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED, android.intent.action.LOCALE_CHANGED, android.intent.action.NETWORK_SET_TIME, android.intent.action.NETWORK_SET_TIMEZONE, android.intent.action.NEW_OUTGOING_CALL, android.intent.action.PACKAGE_ADDED, android.intent.action.PACKAGE_CHANGED, android.intent.action.PACKAGE_DATA_CLEARED, android.intent.action.PACKAGE_INSTALL, android.intent.action.PACKAGE_REMOVED, android.intent.action.PACKAGE_REPLACED, android.intent.action.PACKAGE_RESTARTED, android.intent.action.RADIO_TECHNOLOGY, android.intent.action.REBOOT, android.intent.action.SCREEN_OFF, android.intent.action.SCREEN_ON, android.intent.action.SERVICE_STATE, android.intent.action.SIG_STR, android.intent.action.SIM_STATE_CHANGED, android.intent.action.TIMEZONE_CHANGED, android.intent.action.TIME_TICK, android.intent.action.UID_REMOVED, android.intent.action.USER_PRESENT, and android.provider.Telephony.SPN_STRINGS_UPDATED. 





Word 작업중에 이상하리만큼 저장이 안되서


이것저것 검색해보니


아래와 같은 방법으로 해결가능..



파일 -> 옵션 -> 고급




저장 안되는 문제에서 해방..


언어 데이터 포함 을 체크 해제 해주면된다. 




이 글을 Effective Java를 읽고 적는 글임을 미리 밝힌다. ( 서적에 정확하게 기록되어있다. )

---------------------------------------

아래의 간단한 코드를 보자.

String strInputValue = "I Love You";

System.out.println("["+strInputValue+"]");

if(strInputValue.equals("TRUE"))

{

System.out.println("True");

}


흔하디 흔한 String 변수선언 이후 변수를 출력하고  문자열과 비교 후 일치할 시에 True 라는 문구를 출력하는 코드이다..

너무 쉽다? 그렇다. 너무 쉬운 코드라면 코드다.. 

위 코드에서 strInputValue 의 값을 null 로 변환하면 어떤 일이 벌어질까?





String strInputValue = null;

System.out.println("["+strInputValue+"]");

if(strInputValue.equals("TRUE"))

{

    System.out.println("True");

}





결과

[null]

Exception in thread "main" java.lang.NullPointerException

at com.ncf.test.java.TestClass.main(TestClass.java:13)




읭?

출력에서 null은 잘 찍어놓고..

비교 구문에서 오류를?

 
대학 시절에는. 아래와 같은 구문으로 null 값에 대한 처리를 수행했었다.


if(strValue != null && strValue.equals("test"))
{
System.out.println("Success");
}


대충 위와 같은 코드다... 물론 이도 동작은 한다.

좀 더 깔끔한 코드를 원하는것 뿐이다.


String strInputValue = null;

System.out.println("["+strInputValue+"]");

if("TRUE".equals(strInputValue))

{

System.out.println("Pass");

}




그렇다면 이 코드는 어떤가?

에? 위하고 비교했을때 .. 비교값의 위치가 반대인 것이잖아?

그렇다면 결과는 어떨까?



글을 쓰고 있는 이유와 같이. Null pointer Exception 은 발생하지 않는다.

왜일까?

좌변의 값 떄문이다.

자바에서 비교는 일단 좌측의 값을 기반으로 비교를 행하는데.

상단의 코드의 경우 좌측의 값이 null 이다... 고로 비교 자체를 할수가 없다.


아래의 경우는 좌측의 값이 문자열 TRUE다.. 우측의 값이 null 이므로 다른값으로 간주하게 되는것이다.


간단한 트릭? 이지만, SI를 뛰고 있는 개발자 입장에서 유익하게 사용중이니

가벼운 마음으로 익혀두면 두고두고 나쁠일은 없지 않을까?






 
자 이제 몽고 DB를 좀 주물럭 거려보자..

1. 쉘 접속 ( 1회차를 참조하시라 )

2. Data Insert.

입력에 사용되는 데이터 타입은 JSON 타입이다.

JSON을 잘 모르겠다? 하는 사람은 

http://json.org/ 이곳에 접속해서 그림! 을 잘 따라가면!!! 이해할 수 있을것이다.

JSON은 
{ "key" : "value" } 의 형태를 가진 표현 방법이다.

사용가능한 변수 타입은 차후에 기록하는 것으로 미루고 

쉘에다 데이터를 넣어보자.

> var my insert = { "user" : "blahblah" , 
... "type" : "human",
... "age" : 30,
... "tune" : "no"
... };
Fri Jan 20 00:13:29 SyntaxError: missing ; before statement (shell):1
> var myinsert = { "user" : "blahblah" , 
... "type" : "human",
... "age" : 30,
... "tune" : "no"
... };
> db
framework
> db.test.insert(myinsert)



입력을 했더니 서버 로그가 좌르륵 올라간다.!

뭐지 하고 대충 확인해보니

첫 데이터를 입력하니 DB가 생성되었따는 문구 

그래 가서 확인해보는거야..



오호라... DB 명칭이 framework ...

파일명도 framework.* 

그렇군..



조회를 해보자..

> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "user" : "blahblah", "type" : "human", "age" : 30, "tune" : "no" }



데이터를 아무거나 하나 더 넣고 조회를 해보자.

> var myinsert2 = { "user" : "blahblah2" , 
... "type" : "alien",
... "age" : 26,
... "tune" : "yes"
... };
> db.test.insert(myinsert2)
> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "user" : "blahblah", "type" : "human", "age" : 30, "tune" : "no" }
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }



결과물에 추가로 기록된 _id는 차후에 설명하겠다.. 

일단 데이터마다 가지는 Unique Key라고 기억하면 되겠다..

SELECT * FROM USERS WHERE ID = 'human'

뭐 이런건 어찌 조회하나?
 
해보자..

> db.test.find({"user":"blahblah"})
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "user" : "blahblah", "type" : "human", "age" : 30, "tune" : "no" }
>

 

조회 조건에도 역시 JSON  타입을 사용해서 조회를 해야한다.

find 이외에도 findOne 라는 메소드가 있으니 확인해보자.


수정.
user:blahblah 를 가지는 사용자에 대해

type을 frog로 변경해보자..

> db.test.update(
... {"user":"blahblah"},
... {"$set" : { "type":"frog" } }
... )
> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "age" : 30, "tune" : "no", "type" : "frog", "user" : "blahblah" }
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }
>

 
update 구문을 보면
첫 파라메타로 검색 조건
다음 파라메타로 제한자($set)와 변경할 값을 설정한다.
 

age 수치의 증가.
 
테스트 하다가 깜짝 놀랬는데.. 놀라고 나서 생각해보니 당연하다..

> db.test.update(
... {"user":"blahblah"},
... {"$inc" : { "age":30 } }
... )
> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "age" : 60, "tune" : "no", "type" : "frog", "user" : "blahblah" }
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }
> db.test.update(
... {"user":"blahblah"},
... {"$inc" : { "age":1 } }
... )
> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "age" : 61, "tune" : "no", "type" : "frog", "user" : "blahblah" }
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }



윗줄에서 inc 제한자를 사용하여 30.. 을 설정했는데..

30이 증가되어버렸다.. 원 값인 30을 입력하는건가 하고 생각해서 입력한 값이었는데 60이 되어버렸다 -_- ... 

그래서 다시 1로 테스트 해보니 30 -> 60 -> 61 .. 로 변하는 값을 확인할수 있엇다.


삭제 해보자!

> db.test.find()
{ "_id" : ObjectId("4f18334ee18f4804da05227f"), "age" : 61, "tune" : "no", "type" : "frog", "user" : "blahblah" }
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }
> db.test.remove({"age":61})
> db.test.find()
{ "_id" : ObjectId("4f18344ee18f4804da052280"), "user" : "blahblah2", "type" : "alien", "age" : 26, "tune" : "yes" }
> db.test.remove()
> db.test.find()



사용법은 검색이나, 수정에 사용했던 방법과 유사한거 같다.. 

사용 방법은 위 로그를 참조..




이제 MongoDB가 좀 익숙해 질려한다...




현재 O'REILLY사의 "MongoDB 완벽 가이드"를 보면서

학습식의 글을 작성중인데..

글을 남기는 이유는 강의도 아니고 필요에 의해 검색하기 위함이다.

어려운 질의는 늦게 늦게 답변이 달릴수도 있으니 ! 양해 바랍니다 ㅡ.ㅜ;

 


 
 
 
MongoDB 설치

홈페이지 : http://www.mongodb.org/
 
다운로드 페이지 : http://www.mongodb.org/downloads

Data 폴더 : /data/db

mkdir -p /data/db

다운로드 페이지에서 받은 파일은
/data/mongodb-osx-x86_64-2.0.2
여기에 풀었다..

MongoDB의 실행은

$bin/mongod


db 경로를 설정하려면
 

$bin/mongod --dbpath ~/



자 실행해보자

MongoDB가 설치된 경로

MongoDB 구동



서비스 중인 포트로 접속해보면 1000을 더하면 진단 툴에 접속할수 있을을 알리는 메시지를 노출한다.

진단툴의 모습 주소는 localhost:28017이다.







MongoDB  쉘 실행하기
$bin/mongo

쉘의 기본은 자바 스크립트의 기본을 그대로 사용가능.

변수를 할당한다거나. 수학 연산, 함수 생성등이 가능.



> use framework
switched to db framework
> db
framework


사용할 DB를 설정(use)하고 현재 DB를 확인(db)하는 명령.

글이 길어지니

MongoDB 내에서 CRUD는 2회차로! 미룸!!

 







부우웅....


맥북 에어를 뭔가 좀 쓰다보면 비행기가 마구마구 이륙한다...

사용하고 있는 맥 모델은 MBA 13 2011 후반기 모델..

얇고 이쁜건 사실인데 비행기 이륙소리가 날적마다... 얇디 얇은 이녀석이 잘 버텨줄까 하는 걱정도 이만 저만이 아니다.. ( 물론 잘 설계해서 그럴리는 없겠지만 .. )


위 스크린샷에 선택된 녀석..

MDS  이녀석은 뭐하는 녀석일까?

MetaData Server.

뭐냐 넌.. 

복잡하게 설명할것도 없이.. 맥에서는 항상 파일, 메일 등등에 대해 인덱싱을 하는데 .. 그 일을 하는 녀석..

스샷에야 매우 낮은 점유율을 기록하고 있지만. 이 글을 포스팅 하기 위해서 뭐야?! 할때는 150 까지 치솟았던 녀석이다... ..


Spotlight 기능을 사용하는가? -> Yes -> 그냥 가끔 비행기 이륙하는걸 봐라
No -> 꺼라
Soso -> 꺼라... 꺼도 동작은 한다. SSD같은 경우 파일 탐색에 있어 큰 지장이 없기에 선택은 사용자에게 전가한다.....



MDS 종료방법..

터미널을 열고 

sudo mdutil -a -i off


다시 켜는 방법은

sudo mdutil -a -i on




사용에 일단 지장은 없으나

좀더 써보고 문제가 있을시에는 이 글이 폭파! ....

뭐.. 이 글을 읽는 시점이라면 아마.. 문제없이 잘쓰고있지 않을까요?








 
안드로이드의 가장 큰 문제점이라면

기기별로 해상도가 다르다는점..

 개발사에게는 기기의 다양화를 꾸릴수 있는 거지만


나같은 나약한(?) 개발자에게는 이거 어찌 해야하나.. 하는 탄식이 나오게 하는 큰 문제점이라면 문제점이다.


뭐 오늘도 두어시간 삽질을 통해(?) 수확한 즐거운 꺼리 하나를 투척한다. (얼마만의 블로깅인지 모르겠다.. )


테스트 대상은 가장 널리 퍼져 있는 대표 테스트 단말.

갤럭시 S ( 800 * 480  / hdpi )

갤럭시 탭 7 ( 1024 * 600 / hdpi) - 이하 탭7

갤럭시 탭 10.1 ( 1280 * 800 / mdpi ) - 이하 탭10 / 널리 퍼져 있는 단말은 아닌가? -_- ;;;



1. 전제 조건으로 단일 APK를 뱉어내야할것

2. 갤럭시S기반으로 앱은 개발 되었고

3. 탭7 탭10을 지원해야한다.

4. 이미지 리소스는 확대를 허용한다. 


결론부터 얘기하면 이전 포스팅에서 사용한 방법으로는 구분이 불가하다.

layout
layout-1024x600
layout-1280x800 

요 방법..

이상하게 탭10에서 구동시에는 탭7의 레이아웃을 참조해버린다.. (다른 별도 설정이 있는지는 모르겠다.. )

이래저래 안드로이드 개발자 사이트좀 뒤적거리다가  테스트후에 찾은 결론
(참고 링크 : http://developer.android.com/guide/practices/screens_support.html )


layout
layout-large
layout-xlarge

순서대로 갤S
탭7 탭10을 참조한다.. 짜잔...
갤S랑 갤탭은 해상도가 유사하니 hdpi에 때려넣고 그냥 참조 하여 일부 수정.

탭10은 해상도가 어마어마하게 차이나지만 -_- mdpi 니깐 별도로 이미지를 mdpi폴더에 넣어도 되고

아니면 무식하게 hdpi에 있는 녀석을 복사해서 넣어주면, 그럴싸하게 보여진다.

...... mdpi에 파일이 없으면? 절반 크기 정도로 화면에 노출되는것을 알수 있다.

결과로 뱉어내는 APK 용량이 문제라면 문제지만.. (당연한것이다. 고밀도 이미지와 중밀도 이미지를 복수로 저장하고 있으니.. )

단일 APK로 뱉어내야만 하는 상황이라면

충분 고려해 볼만한 개발방법.. (폴더관리? )

이상 .







 
안드로이드 리소스 사용에 대해

다양한 해상도 및 DPI지원에 대해


layout-1024x600
drawable-hdpi-1024x600

이런식으로 폴더 작성후 레이아웃이나 이미지를 넣어줄시에

해당 사항에 맞는 리소스를 불러들인다..

코드 삽질을 줄여주는 중요한 요소중 하나 :)

 


그렇다면 언어 설정은?

drawable-ko
drawable-en
 
공통요소는 drawable 에 :)




  ------------------

댓글에 욕설(?) 이 없는걸로 보아 참고하신 분이 없는거 같군요. (은근 다행입니다 ;; )

과거 .1024*600 에서 1024x600 으로 오타 수정하였습니다. 


http://gtko.springnote.com/pages/5254593.xhtml


검색중에 솔깃한 URL 발견..

Intent FLAG  정리

TextView 에 URL을 낑궈 넣을수 있는

Linkfy 설정 등.

유용한 기술들이 기록되어있다...



통화

#758353266#646#

입력이후 리붓되고나서

USIM 다운로드가 진행되면 완료 :)










내 대화패턴이 저중에 속한건 없는가.

내가 지금껏 다툼이나 싸움에 있어

저런 발언을 한적이 없는가...

하지 않도록 노력하자.

안드로이드에서 제공하는 

스택의 크기는.

8KB..

아 작다 ( --);;; 모바일 환경이니 그러려니.. 하지만서도

Recursive좀 굴리다보면

훌쩍 초과하는게 8kb...


8kb이상을 사용할려면 쓰레드 그룹을 만들어서

최대 스택 크기를 늘리는 방법!

아래 코드 참조 ( --);

Runnable r = new Runnable(){
@Override
public void run() {
// Do SomeThing
}
};
ThreadGroup tGrp1 = new ThreadGroup("ThreadGrp00001");
Thread a = new Thread(tGrp1,r, "Thread Name", 1024*256) ;
a.start();


최대 크기는 256kb.

개발자 포럼에 가보니..

그 이상은 어떻게 사용이 가능하냐는 질의에...

최적화 해라 -_- 라는 아름다운 답변..



그럼 즐 코딩~ 

애플 앱 개발자로서 누구나 보고있는

애들 개발 문서들..

아이폰 / 아이패드에서 iBooks를 통하면 쉽게 접할수 있다...

iBook -> 스토어 -> 검색 : "Apple Developer"

총 6권의(국내계정은 5권) 전자문서(아마ePub)를 받을수가 있다...

PDF 리드용으로 Stanza(여기서 이미 애플 개발문서 (PDF) 를 보는데 느리다 ㅡ.ㅡ )를 쓰고있는데. 스토어에서 받은 녀석은

생각보다 훨씬 빠른 속도로 동작한다.. 파일 포멧의 차이인가;;



참고 링크

http://wikitree.co.kr/main/news_view.php?id=25405


iTether로 정상적으로 연결된 상태인데

인터넷에 연결할수 없다는 메시지가 등장할 때

해결방법..


1. iPad에서 등록된 iPhone을 삭제한다.

2. iPhone에서 등록된 iPad를 삭제한다.

3. iPad에서 다시 iPhone을 등록한다.(블투 )


이상없이 동작하면 즐긴다 :)


...

아이패드에서만 백날 삭제해봐야 아이폰에서 꼬인거라 동작을 안하더군요.

이래저래 검색해보니

아이폰의 블투 데몬이 상태가 안좋을때가 있어서 그렇다네요.

정확한 원인은 미확인으로 (귀.. 귀찮아서 ;; ) 남기고

간만의 포스팅은 끝!;
내가 쓸려는 User 테이블..

Primary Key로 이미 두개의 값이 잡혀있다...

phoneNumber , nickName

타 테이블(대략 10개쯤) 저 값을 참조하고 있어서 

1. ALTER TABLE User ADD idx int(11) NOT NULL AUTO_INCREMENT;
2. ALTER TABLE User ADD idx int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT;

안먹는다 -_-.. 당연하다..

자동 증가값은 KEY가 아니면 안된다.

그렇다면 키를 해제!


ALTER TABLE User DROP PRIMARY KEY;
ALTER TABLE User DROP PRIMARY KEY (nickName,phoneNumber);

안된다 -_- 다른 테이블 참조 다 끊던가.




어쨋든 User에 순번을 추가해야하는 상황..

모로가도 서울로 가면된다.!

Unique Key.. (어디서 들었는데 검색하다 급 눈이 반짝 *.* )


ALTER TABLE User ADD idx int(11) NOT NULL UNIQUE KEY AUTO_INCREMENT;

그래서 이것!..

성공~ .~




PRIMARY KEY와 별개로 설정이 가능하고 중복을 방지해준다.

PRIMARY KEY로 선언할수 없는 상황에서 사용하면 나름 유용할듯하다..




P.S. DB Schema 설계할때,  안쓰더라도 idx는 기본으로 좀 넣어주라 ㅠ.ㅠ. 제발;;(모 님 찔리십니까? )






ALTER TABLE [[[TableName]]] AUTO_INCREMENT = [[[VALUE]]];

Table에서 AutoIncrement 값을 사용하다가 특정 값으로 설정해줄때.
예를들어 
신규 테이블(TblBoardFree) 생성 -> 시작번호를 10001번으로 하고싶으면

ALTER TABLE TblBoardFree AUTO_INCREMENT = 10001;

다음에 신규로 추가한 항목은 10001번의 값을 가지게된다.




P.S. 자주 쓰는데 자꾸 잊어버린다 ㅡ.ㅜ;


요즘 검색해보니 원클릭 루팅이 있더군요..

아래 과정을 한방에(?) 진행해주는 녀석 같습니다.

+ 사용에 대한 책임은 모두 본인이 지고 가는겁니다..


================================================

간략하고 텍스트 위주의 모토로이 루팅 방법에 대해 기록하겠습니다.

기존 전제조건은

1. 모토로이  USB 드라이버가 설치된 상황 [ 요거 하나; ]



널리고 널린 첨부 파일

다음을 다운받아서 압축을 풀고


1. USB연결
2. 상단 USB 연결 메뉴에서 "모토로라 휴대전화도구" 선택
3. 바탕 -> 메뉴버튼 -> 설정 -> 응용프로그램 -> 알수없는 소스 ON 
4. 3에 이어 개발 메뉴 -> USB 디버깅 ON 켜진상태로 유지 ON
5. 설정 -> Wifi OFF BlueTooth Off
6. 계정및 동기화 -> 백그다운드 데이터 OFF (자동으로 자동 동기화 OFF)

Console 을 열어 (Win + R : cmd [enter] )
adb push Superuser.apk /sdcard/superuser.apk
adb push su /sdcard/su
adb push busybox /sdcard/busybox
adb push exploid /sqlite_stmt_journals/exploid
adb shell

cd sqlite_stmt_journals
chmod 755 exploid
./exploid
rootshell 


여기 rootshell 을 실행하기 까지 여분의 시간이 소요됩니다.(기다렸다가 입력하세요)

패스워드를 묻는 곳에서

secretlol 

cp /sdcard/superuser.apk /system/app/superuser.apk
cp /sdcard/su /system/bin/su
cp /sdcard/busybox /system/bin/busybox
chmod 4775 /system/bin/su
chmod 4775 /system/bin/busybox
rm /system/bin/rootshell

exit
exit

adb shell
su

모토로이 화면에서 Allow 선택
이상루팅끝

기타 설치 추천(?) 어플.

Estrongs File Explorer : 무료 파일 매니저

My Market : 해외 무료 게임 마켓 접근 가능

MilestoneOverclock12 : 오버클러킹 
Launcher Pro : 빠른 홈 런처

Mini Info : 배터리, 내장 매모리, SD 용량  위젯

APNDroid : 3G차단 위젯

Advanced Task Killer : 작업관리자 ( 위젯 강추 )



즐거운 안드로이드 생활이 되시길!

Enjoy!

프로젝트를 진행하던중


수많은 리소스로 골머리가 솔솔 아파왔는데!

어라? 폴더에 폴더 추가해서 쓰면 

그래도 좀 보기는 편하겠네?



.. 일단 결론은 안됩니다...

@drawable/lv2/img블라블라..


값 자체를 

해석하지를 못하는건지 어쩐건지






위 이미지와 같은 구조에 대해 지원을 해주지 않으므로(혹시 가능한 방법을 알고 계시면 알려주세요 ㅠ.ㅠ. )

file명을 잘 지어서 임시로 회피하세요...

뭔가.. 다른곳에 문의를 해봐야겠습니다.




View v;

LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);

TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);

return v;


뭔가 미묘하게 문제 스럽지만

중요한 코드들은 다 잘 들어가있는 Layout Inflater...

return v 대신에 setContentView(v)식으로 선언해주면 

Activity내 onCreate에서 바로 화면에 설정도 가능하다는점...

참고하세요 :)




+ Recent posts