SCJP 자격증은 J2SE (Java 2 Platform, Standard Edition) 기반의 Java Programming 언어에 대한 기본적인 지식을 기반으로 Java의 능률성을 실행하는데 관심이 있는 프로그래머들을 위한 자격증입니다. Java 기술을 직접 개발한 썬 마이크로시스템즈에서 Java Programming 언어에 관련된 지식을 표준화된 방식으로 검증해 주는 시험이며, 또한 Java 기반의 모든 툴 개발에 필요한 기초 지식을 인정 받을 수 있는 자격증입니다. 자바 프로그래머라면 기본적으로 본 자격증을 취득하시기를 권장해 드립니다.
기본적인 원리를 살펴보면 너무 너무 간단하다. 모든 퀴즈가 그렇듯이.. 답을 보면 신기하면서도 허무한 마음 ㅋ 이었으나 답이 아니군 -_-
잘려진 막대 중에서 가장 길이가 긴 것을 찾는다. 잘리기 전의 막대는 이것보다 길기 때문에 이 값에서 시작하여 모든 막대 길이의 합(전체가 하나의 막대로 이루어진 것을 토막낸 경우)까지가 답이 될 수 있는 값이다. 이제 루프를 돌면서 가능한 모든 값들에 대해서 조합이 가능한지를 확인하면 되는데..
1. 사용하지 않은 막대기를 우선 내림차순으로 정렬한다. 2. 사용하지 않은 막대 중에서 가장 긴 막대기를 뽑는다. (정렬된 막대 중에 첫번째 선택) 3. 나머지 막대들과 선택된 막대들을 조합하여 답이라고 예상되는 값을 초과하는지 체크. 4 .초과하지 않을 경우 해당 막대를 선택하고 위 과정을 재귀적으로 반복.
문제의 예제에 적용해 보면 입력 : 5, 2, 1, 5, 2, 1, 5, 2, 1
내림차순으로 정렬 - 5, 5, 5, 2, 2, 2, 1, 1, 1 답이 될 수 있는 값은 5 ~ 24 사이에 있으므로 5부터 루프를 돌면서 확인한다.
1. 5 선택 남은 막대 : 5,5,2,2,2,1,1,1 완성 (5) 2. 5 선택 남은 막대 : 5,2,2,2,1,1,1 완성 (5), (5) 3. 5 선택 남은 막대 : 2,2,2,1,1,1 완성 (5), (5), (5) 4. 2 선택 남은 막대 : 2,2,1,1,1 완성 (5), (5), (5) 조합중 (2) 5. 2 선택 남은 막대 : 2,1,1,1 완성 (5), (5), (5) 조합중 (2, 2) 5. 2 선택 남은 막대 : 1,1,1 완성 (5), (5), (5) 조합중 (2, 2, 2) <- 5를 초과 6. 1 선택 남은 막대 : 2,1,1 완성 (5), (5), (5) (2, 2,1) 7. 2선택 8. 1선택 9. 1선택 ----- 모두 사용했지만 길이가 5인 조합을 완성할 수 없음 -> 6이 답인지 확인
1. 5 선택 남은 막대 : 5,5,2,2,2,1,1,1 조합중 (5) 2. 5 선택 남은 막대 : 5,2,2,2,1,1,1 조합중 (5,5) <- 6을 초과하므로 선택하지 않음 3. 5 선택 남은 막대 : 5,2,2,2,1,1,1 조합중 (5,5) <- 6을 초과하므로 선택하지 않음 4. 2 선택 남은 막대 : 5,5,2,2,1,1,1 조합중 (5,2) <- 6을 초과하므로 선택하지 않음 5. 2 선택 남은 막대 : 5,5,2,2,1,1,1 조합중 (5,2) <- 6을 초과하므로 선택하지 않음 6. 2 선택 남은 막대 : 5,5,2,2,1,1,1 조합중 (5,2) <- 6을 초과하므로 선택하지 않음 7. 1 선택 남은 막대 : 5,2,2,2,1,1 조합중 (5,1) <- 완성 .. ..
.. 1 선택 남은 막대 : 완성 (5,1) (5,1) (5,1), (2,2,2)
-----
모든 막대를 사용하여 6의 조합을 만들었음 -> 답은 6
위의 알고리즘을 어떻게 구현하느냐는 여러 방법이 있겠지만 소스 코드를 보면 막대를 저장하는 배열 하나와 막대의 사용여부를 저장하는 boolean 배열, 이렇게 두 가지를 사용한다.
-------------------- 진짜 이문제 풀려구 무지하게 고민했는데 ㅋ
내림차순으로 정렬해서 Greedy choice를 하는 걸로 해서 가장 길이가 긴 막대를 선택하는 방법으로 해서 예상 값을 초과하면 다른 막대를 선택하는 과정을 반복하는 것까지는 생각했는데..
위 소스코드에서처럼 일단 모든 막대를 사용했을 경우에 무조건 답이 아니라고 판단해서는 안된다고 생각했기때문에 (다른 방식으로 조합하면 답이 될 수도 있으므로) 조합의 방법을 바꿔보기 위해서 특정막대를 선택하기 이전으로 돌아가기 위한 방법이 필요하다. 근데 그걸 어떻게 하면 되지..ㅠ_- 에서 좌절했다.
답이라고 예상하는 값을 초과할 경우 선택하지 않는 방법을 통해서 답이 될 수 없는 조합을 제거하고 재귀적인 호출 방식으로 모든 조합을 확인할 수 있었나보다.. -> 안되잖아 -_-
휴대폰용 OS인 심비안에서 작동하는 악성코드 샘플들을 카스퍼스키에 진단한 후에 V3의 DB와 비교해서 기진단 여부를 확인하고 결과를 출력해주는 프로그램
삽질도 많이 했지만 지나가다 한 마디씩 던져주시는 말을 붙들고 열심히
내가 머리를 쥐어뜯고 있으면 지나가시던 이상철 선임님이 물어보신다..
그래서 내가 이러이러하게 하고 싶은데 요게 잘안되요.. 설명을 하면 그럼 요기가 안되겠네.. 하면서 바로 찍어주신다.. 그럼 놀랍게도 적중.. 난 거기에서 에러가 날꺼라곤 생각지도 않았는데-
그래서 어째서 그렇게 잘 아시죠? -_- 하면 프로그램 구조만 잘 파악하면 안될꺼 같은 부분이 보인다고 하신다.. 다 경험에서 우러나오는 거라고.. (역시 막강한 내공)
근데 이게 맞는 말인거 같긴 하다.. 나도 내가 이번에 삽질한 게 있어서 담에 똑같은게 나오면 좀 더 쉽게 눈치를 챌 듯 싶다.
결국 완성! 내 자리에서 잘 돌아가던 프로그램이었고 몇 번이나 테스트 했으니까 나름 자신감은 있었지만 잘하는 사람한테 확인을 받아야하니 살짝 쫄아서 숙제 검사 받는 기분으로 가지고 갔다.
그런데 이승희 주임님 자리에서 돌리니까 온갖 에러가 다 나는 거다.. 완죤 급당황해서 내 자리에선 잘 됐는데 왜 이러지 -_-;; 하면서 보니까 많은 원인이 있었다..
1. 실행시에 인자로 샘플들이 들어있는 경로를 입력해야되는데 그걸 상대경로로 입력을 했음. 프로그램 내부에서 CreateProcess 로 카스퍼스키를 실행하면서 그 상대경로를 그대로 넘겨줬더니 카스퍼스키 실행파일을 기준으로 상대 경로를 계산해서 완죤 난리난거였다.
2. 테스트 할 때 경로를 단순한 형태로 넘겨줬었는데 이주임님이 테스트 할 때는 "My Document\Test folder\Samples" 이런 식이어서 중간에 공백이 있었던거다. 그래서 또 엉망..ㅠ_-
3. 카스퍼스키 로그를 기록하는 옵션이 달라서 내가 테스트 할 때랑은 로그의 형태가 완전히 달라진거였다. 당연히 파싱이 제대로 될 리 만무..
4. 카스퍼스키 진단명을 V3 진단명으로 바꾸는 과정에서 이주임님이 나한테 이야기 안해줬던 부분이 있어서 거기서 또 안맞아들어감
간단한 이유로 발생한 문제들이지만 그런만큼 발견하기도 쉽지 않았고 해결하면서 몇 번이나 왔다갔다해야했다. 그러면서 당연히 코드는 여기저기 if 문으로 누더기가 되어가고 ㅠ_- 내가 코딩하는 환경하고 테스트하는 환경이 그렇게나 차이나는 걸 알고나서 그냥 그 자리를 뺏어 앉아서 개발을 하고 싶었다 -_-
이런 이야기를 이상철 선임님께 했더니 원래 그런거라 하신다. 중간 중간에 요구사항을 주기적으로 확인해서 반영하지 않으면 막판에 완전 낭패보기 십상이라고..
다른 프로그래머가 나한테 부탁한 일인데도 이 정도라면 컴퓨터를 아예 모르는 고객이라면 날 잡아먹으려들지도 모른다는 생각이 들었다. 그리고 코딩이 결코 쉬운 일이 아닐꺼라는 생각이 팍팍 든다..
그래도 이번에 많은 걸 배울 수 있었다. 익숙지 않았던 많은 라이브러리들을 사용해 볼 수 있었고 개발 과정에서 혁민이가 만들어놓은 문자열 파서나 인터넷에서 구한 MD5 추출 루틴 등 다른 사람이 만들어놓은 모듈을 가져다 쓰기도 했다.
내가 만든 여러 프로시져를 클래스로 효과적으로 나누어 나중에 내 프로그램이 확장되기 쉽도록 객체지향 개념을 어설프게나마 적용해 본 것도 많은 도움이 되었다. 어느 정도 큰 규모의 프로그램을 보면서 구조도 익힐 수 있었고 디버깅을 하는 감도 조금 늘었지싶다.
무엇보다..
- 어떤 로직을 구현하는데 있어서 에러는 의외로 간단한 부분에서 난다는 것. - 기본적인 예외 처리는 무조건 해주어야한다는 것 (예 : 파일 입출력 시 파일이 존재하는지 확인) - 각 모듈 사이에서 처리가 끝난 정보를 넘겨줄 때 그것이 원하는 형태로 전달되는지 확인할 것. - 특정 환경이나 조건을 임의로 가정하지 말고 일반적인 상황에서 코딩하고 테스트 할 것.
예전에 어디선가 이런 말을 봤었는데...
사용자는 결코 프로그램에 우호적이지 않다. 가능한 모든 문제를 일으키고 경고를 무시하고 프로그램을 자기 마음대로 사용할 것이다.
페렐만의 살아있는 수학 /야콥 페렐만 수학을 즐길수는 없을까 /브누아 리토 수학으로 이루어진 세상 /키스 데블린 문제 해결의 이론과 실제 /한인기, 꼴라긴Y.u.m 공저
수학과 친해지려는 몸부림 ㅋ 내일 집에 내려가면서부터 동원 예비군 갈 때까지 쭉 읽어줄테다.. 기초가 튼튼해야 하는 법.
그나저나 책 빌리러 가는 길 - 학교는 축제기간.. 축제 부스나 주점은 썰렁한데 시끄러운 노래 소리가 들리는 걸로 봐서 가수들이 공연을 하나보다. 학생이 주체가 되서 즐기는 행사가 원래 별로 없었지만 ㅋ 밤에 쓸쓸하게 남아있는 부스들을 보니까 좀 보기 그렇더라
그래도 축제라 놀고 있는 녀석들이 없을까 친구들 한테 전화해보니 다들 프로젝트다 졸업 작품이다 바빠서 놀아주지도 않는다.. 혼자 힐끔거려 봤는데.. 도서관 뒷쪽 무대에서 웬 아가씨들이 대기하고 있다. 얼핏 봐도 우리 학교 학생은 아닌 거 같고 다음에 공연하려고 기다리는 가수들 같은데..
생각보다 나이가 어려보인다. 내가 나이가 먹긴 먹었나 -_- 비슷한 또래거나 어려보이는건 뭐야..
별로 예쁘다고 느껴지지 않는다. 화장을 하고 화려한 조명 아래서 야시시한 옷을 입고 있는데도..
울 아가씨랑 같이 산책이나 하면 좋을꺼 같은 선선한 봄날의 저녁~ 인생의 행복은 결코 멀리 있지 않다고 했거늘.. 나한텐 멀군하ㅋ
A CLSID is a globally unique identifier that identifies a COM class object. If your server or container allows linking to its embedded objects, you need to register a CLSID for each supported class of objects.