2007년 4월 30일 월요일
불면증에 시달리고 있습니다..
현재 일주일째 불면증에 시달리고 있습니다..
일찍자야.. 3시.. 평균 4~5시 잠이 듭니다..
출근은 7시에 일어나서 하고요..
원래 버스에서 잠을 청하곤 했는데 버스에서도 조차 잠들지 않는군요..
오늘은.. 한숨도 못잤습니다.. 최고조에 이른거 같습니다..
직장.. 미래.. 이직.. 연봉.. 생활... 이모든것이 원인인듯 싶습니다..
잠을 자고 싶습니다.. 힘드네요..
2007년 4월 28일 토요일
개발자 격언...
1. simple is best.
- 좋은 프로그래머는 사람이 이해할 수 있는 코드를 짠다. - 마틴 파울러
- 짧게 쓸 시간이 없어서, 대신에 길게 쓰도록 하겠습니다. - 마크 트웨인
기계가 빠르게 이해하는 코드가 사랑받는 시기는 갔다.
사람(프로그래머)이 이해하기 쉬운 코드가 사랑받는 코드이다.
2. 입력값 체크는 프로그래밍의 40%이다.
입력값을 체크 안하고 어떻게 정상적으로 프로그램이 돌거라 생각하는지...
정말 특이한 개발자들 많다.
해커가 정상적인 루틴 이외에 방법으로 들어왔을때 그 값들을 그냥 DB에 넣을건지 ㅡㅡ
정 입력값 처리하기 싫으면 코맨트에 아예 써놔라.
"// 가정 1. 변수 A 는 항상 문자열만 들어온다. NULL 불가"
"// 가정 2. 변수 B 는 항상 숫자만 들어온다. NULL 불가"
다른 개발자라도 그거 수정해서 에러 안나게 할것이다.
여기서 고민되는것이 메소드 안에서 변수를 체크할것인가, 아니면 메소드를 호출하는 곳에서 할것인가...
메소드 안에서 체크하는 것이 정답이다.
어떤 값을 메소드에 보내든 메소드 자체는 항상 무결하기 때문이다.
정상적인 개발자라면 메소드에 변수를 보내기 전에 확인하긴 하겠지만, 그래도 메소드 내부에서도 체크해야 한다.
입력값은 언제든 어디서든 항상 철저히 체크해야 한다.
3. 머리로 디버깅하고, 컴파일러로 확인한다.
처음에는 머리로 아무리해도 안될거같지만, 연습하면 가능하다.
세상 그 어떤 디버깅 툴보다 좋은것이 사람 머리이다.
연습하고 연습하면 가능한 것이다.
여러분도 가장 뛰어난, 거기다 설치할 필요도 없는 디버깅툴을 가지고 싶지 않은가.
4. 좋은 개발자는 도구를 탓하지 않는다.
어제까지는 멋진 개발자였는데 개발툴에서 IDE 를 뺏어가서 갑자기 개허접 개발자가 되었다.
이런건 말도 안된다.
정상적인 개발자는 메모장가지고도 8-90%까지 하던거 한다.
심지어는 컴파일러 없이도 대부분 개발해놓고 컴파일러 생기면 디버깅할수도 있다.
5. 하드웨어 발전은 낙관적으로, 소프트웨어 발전은 비관적으로.
기계는 누구나 알듯이 빠르게 발전한다.
따라서 (비교적 작은) 돈만 들이면 업글이 가능하다.
그러나, 사람을 업글하는건 쉽지 않다.
따라서, 서버의 부하가 좀 있더라도, 사람(개발자)이
이해하기 쉬운 코드는 좋은 코드이다.
물론... 아주 엄한 코드는 제외.(for 문 내에서 무언가 생성하는 등등)
6. 소스에 자기 이름을 남기자.
최소한 소스 상단에 자기 이메일 주소를 남기자.
만약 이 소스가 정상적으로 작동한다면 연락할 그런 심심한 사람은 없다.
그러나, 정상 작동 안한다면 연락할 것이다.
7. 않될땐 안된다.
안될때가 있다. 그럴때 더 붙잡고 있는것은 시간낭비이다.
차라리 다른것을 하거나, 집에가서 발 씻고 자는게 낫다.
다음날 보면 소스가 다르게 보일것이다.
급하면 급할수록 더 코딩은 안된다. 급할수록 더더욱 마음을 편히 만들자.
조금씩 길이 보이게 된다.
프로그래밍이 늦어지는것은 타자가 늦어서가 아니다.
길이 안보이기 때문이란것 잊지말자.
8. 아닌건 갈아엎는게 낫다.
가끔 너무나 심하게 잘못 코딩되어 있는 소스를 보게 된다.
그럴때는 갈아엎는것도 하나의 방법이다.
9. 일정은 항상 예상치보다 1.5배 잡는다.
지나치게 빡빡한 일정은 언젠가는 사고를 일으킨다.
또한, 코딩은 언제나 위험성이 잠재되어 있는 작업니다.
그 작업중에 일정에 못맞추는 일이 생기면 납기를 놓치게 될것이다.
10. 2 대 8 법칙.
꽤나 유용한 법칙이다.
20%의 코드에서 80%의 에러가 발생한다.
20%의 코드에서 80%의 서버부하가 발생한다.
20%의 웹페이지가 80%의 조회수를 일으킨다.
2007년 4월 20일 금요일
Java SE의 정규표현식 ...
한국 썬 개발자 네트워크 메일링에 가입했는데,
메일을 보니 괜찮은 정규식에 관한 팁이 있어 포스팅.
-------------------------------------------------------------
정규 expression
또는 regex
지원은 버전 1.4 이후 자바 플랫폼의 일부가 되어 왔다. java.util.regex
패키지에서 발견되는 regex
클래스는 펄 언어가 제공하는 것과 유사한 패턴 매칭을 지원하지만 자바 언어 구문 및 클래스를 사용한다. 패키지 전체는 Pattern
, Matcher
및 PatternSyntaxException
의 3가지 클래스로 제한된다. 버전 1.5에서는 MatchResult
인터페이스가 소개되었다.
두 클래스 Pattern
및 Matcher
를 함께 사용한다. Pattern
클래스를 사용하여 정규 표현식을 정의한 다음, Matcher
클래스를 사용하여 입력 소스에 대해 패턴을 검사한다. 표현식에서 패턴에 구문 오류가 있으면 예외가 발생한다.
두 클래스 모두 구성자를 가지지 않는다. 대신, 정규 표현식을 컴파일하여 패턴을 얻은 다음 반환된 Pattern
에게 일부 입력 소스를 기반으로 해당 Matcher
를 요청한다.
Pattern pattern = Pattern.compile( <regular expression> );
Matcher matcher = pattern.matcher( <input source> );
Matcher
를 얻었으면 일반적으로 입력 소스를 처리하여 포함된 모든 매칭을 찾는다. find()
메소드를 사용하여 입력 소스에서 패턴의 매칭을 찾는다. find()
에 대한 각 호출은 마지막 호출 위치에서 계속되거나 첫 번째 호출 위치 0에서 계속된다. 그런 다음 매칭되는 항목이 group()
메소드에 의해 반환된다.
while (matcher.find()) {
System.out.printf"Found: \"%s\" from %d to %d.%n",
matcher.group(), matcher.start(), matcher.end());
}
다음 코드는 기본적인 정규 표현식 프로그램을 보여 주며 사용자가 정규 표현식과 비교 대상 문자열을 입력하도록 메시지를 표시한다.
import java.util.regex.*;
public class Regex {
public static void main(String args[]) {
Console console = System.console();
// Get regular expression
String regex = console.readLine("%nEnter expression: ");
Pattern pattern = Pattern.compile(regex);
// Get source
String source = console.readLine("Enter input source: ");
Matcher matcher = pattern.matcher(source);
// Show matches
while (matcher.find()) {
System.out.printf("Found: \"%s\" from %d to %d.%n",
matcher.group(), matcher.start(), matcher.end());
}
}
}
그러면 정규 표현식의 모양은 정확하게 어떠한가? Pattern
클래스는 보다 세부적인 사항을 제공하지만 기본적으로 정규 표현식은 다른 문자 시퀀스와 일치시킬 문자 시퀀스이다. 예를 들어, "Hello, World"
문자열에서 두 개의 L자("ll"
) 문자열 리터럴 패턴을 찾을 수 있다. 앞의 프로그램은 시작 위치 2와 끝 위치 4에서 "ll"
패턴을 찾을 것이다. 끝 위치는 일치된 문자열 패턴의 끝 이후에 다음 문자의 위치이다.
"ll"
같은 패턴 문자열은 입력 소스에서 문자적으로 위치하는 지점만을 보고하므로 그리 흥미롭지 않다. 정규 표현식 패턴은 특수 메타 문자를 포함할 수 있다. 메타 문자는 정규 표현식에서 강력한 매칭 기능을 제공한다. 정규 표현식에서는 "([{\^-$|]})?*+."
의 15문자를 메타 문자로 사용할 수 있다.
일부 메타 문자는 문자 그룹을 나타낸다. 예를 들어, 대괄호([ 및 ]
)를 사용하면 대괄호 안의 문자 중 하나가 텍스트에서 발견되는 경우 매칭이 성공하는 일련의 문자를 지정할 수 있다. 예를 들어, "co[cl]a"
패턴은 coca 및 cola라는 단어와 매칭된다. []
는 단일 문자를 매칭하는 데만 사용되므로 cocla는 매칭되지 않는다. 몇 가지 매칭을 해 보고 문제가 없으면 곧 수량자에 대해 자세히 살펴보자.
개별 문자의 매칭 이외에 대괄호 문자([ 및 ]
)를 사용하여 [j-z]
로 지정된 j-z
의 문자처럼 일정 범위의 문자를 매칭할 수 있다. 이러한 문자 범위는 "foo[j-z]"
처럼 문자열 리터럴과 결합할 수도 있다. 여기서 fool을 찾으면 매칭이 성공하고 food를 찾으면 매칭이 실패한다. l
은 j
와 z
사이의 범위 안에 있지만 d는 그렇지 않기 때문이다. ^
문자를 사용하여 문자열 리터럴 또는 문자 범위의 제외를 나타낼 수도 있다. "foo[^j-z]"
패턴은 foo로 시작하고 j
에서 z
사이의 문자로 끝나지 않는 단어를 찾는다. 따라서 이번에는 food라는 문자열이 매칭에 성공한다. [a-zA-Z]
처럼 여러 범위를 결합하여 a
에서 z
사이의 소문자와 대문자를 나타낼 수도 있다.
정규 표현식을 처음 학습할 때는 문자열 리터럴이 유용하지만 정규 표현식에서 대부분의 사람들이 사용하는 보다 일반적인 요소는 미리 정의된 문자 클래스이다. 여기서 메타 문자 .
및 \
가 사용된다. 마침표(.
)는 임의 문자를 나타내는 데 사용된다. 따라서 정규 표현식 ".oney"
는 money 및 honey와 매칭되며 oney로 끝나는 5
자의 어느 단어와도 매칭된다. 반면에 \
는 다른 문자와 함께 사용되어 전체 문자 집합을 나타낸다. 예를 들어, 숫자 집합을 나타내기 위해 [0-9]
를 사용할 수 있지만 \d
를 사용할 수도 있다. 숫자가 아닌 문자 집합을 나타내기 위해 [^0-9]
를 사용할 수도 있다. 또는 \D
의 미리 정의된 문자 클래스 문자열을 사용할 수 있다. 이러한 모든 문자 클래스 문자열은 모두 기억하기가 어려우므로 패턴 클래스에 대한 자바 플랫폼 문서에 정의되어 있다. 다음은 미리 정의된 특수 문자 클래스의 하위 집합이다.
* \s -- whitespace
* \S -- non-whitespace
* \w -- word character [a-zA-Z0-9]
* \W -- non-word character
* \p{Punct} -- punctuation
* \p{Lower} -- lowercase [a-z]
* \p{Upper} -- uppercase [A-Z]
미리 정의된 문자열과 관련하여 지적해야 할 사항은 즉각 눈에 띄지 않는다. 위의 Regex
프로그램에 이러한 문자열 중 하나를 사용하려면 표시된 대로 입력한다. \s
는 공백과 매칭된다. 하지만 자바 소스 파일에서 정규 표현식을 하드 코딩하려면 \
문자가 특별하게 취급된다는 것을 기억해야 한다. 소스에서 이 문자열을 다음과 같이 이스케이프해야 한다.
String regexString = "\\s";
여기서 \\
는 문자열에서 하나의 백슬래시를 나타낸다. 다른 문자열 리터럴을 나타내기 위한 기타 특수 문자열은 다음과 같다.
* \t -- tab
* \n -- newline
* \r -- carriage return
* \xhh -- hex character 0xhh
* \uhhhh -- hex character 0xhhhh
수량자는 정규 표현식을 더욱 흥미롭게 만드는데 문자 클래스 같은 기타 표현식과 결합될 때는 특히 그렇다. 예를 들어, a-z
에서 3자의 문자열을 매칭하기 위해 "[a-z][a-z][a-z]"
패턴을 사용할 수도 있지만 그럴 필요가 없다. 문자열을 반복하는 대신 패턴 다음에 수량자를 추가하면 된다. 이 예제의 경우, "[a-z][a-z][a-z]"
는 ":[a-z]{3}"
으로 나타낼 수 있다. 특정 수량에 대해 숫자가 {}
괄호 안에 들어간다. ?, * 또는 +
문자를 사용하여 0번 또는 한 번, 0번 이상, 한 번 이상을 각각 나타낼 수도 있다.
[a-z]?
패턴은 a-z
의 문자와 0번 또는 한 번 매칭된다. [a-z]*
패턴은 a-z
의 문자와 0번 이상 매칭된다. [a-z]+
패턴은 a-z
의 문자와 한 번 이상 매칭된다.
수량자는 주의해서 사용한다. 0번 매칭을 허용하는 수량자에는 특별한 주의를 기울여야 한다.
괄호 기호({}
)를 수량자로 사용할 때는 범위를 지정해야 한다. {3}
은 정확히 3
번을 의미하지만 {3,}
은 적어도 3
번을 의미한다. 수량자 {3, 5}
는 3
번에서 5
번까지의 패턴과 매칭된다.
정규 표현식에는 여기서 살펴본 것보다 훨씬 많은 내용이 있다. 특정 상황에 맞는 정규 표현식을 사용하는 것이 중요하다. 앞의 Regex 프로그램을 사용하여 몇 가지 표현식을 시험해 보고 기대했던 결과가 나오는지 확인해 본다. 여러 가지 수량자를 사용하여 각 차이가 어떻게 나오는지 이해할 수 있도록 한다. 일반적으로 수량자는 가능한 매칭에 대해 최대 수의 문자를 포함하려고 한다.
정규 표현식에 대한 자세한 내용을 살펴보려면 자바 온라인 자습서의 정규 표현식 편을 참고한다.
또한 패턴 클래스에 대한 내용은 javadoc을 참고한다.
방화벽에 막힌 메신져를 사용하자.
삼성이나, 기타 대기업들은 사내에서 MSN, NateOn등을..
사용못하게끔 막아놨다. 그러나 이를 사용할수 있게 해주는 유틸이 있다.
무료였는데 유료로 전환되었다..
다른 프로그램도 있는거 같은데..
그냥 담배 한갑 사는셈 치고 결제 하고 편하게 쓰면 된다.
http://sconnect.co.kr
2007년 4월 16일 월요일
기계식 키보드 Filco Majestouch FKB104M 청소후기~!
얼마전에 (3. 31에 했는데 지금에서야..) 벼르고 벼르던 키보드 청소를 감행했습니다.
걸린시간은 무려.. 3시간 20분 정도? -_-;
허리 끊어지는지 알았습니다. 근데 해놓고 보니 완전 새거 같네요~
요즘 일을 안하고 있어서 요놈 모셔두고 있는데 언넝 일하고 싶은 충동을 생기게 해주는 넘입니다~
키캡이 우레탄 재질이여서 때가 끼기 떄문에 살짝젖은 헝겁으로 청소해 주시면 되겠습니다. :)
작업하면서 찍은 사진을 보시려면 아래 클릭~
more..
오늘의 준비물입니돠~
키캡을 분리하기 위해 준비된~
손톱손질하는..(명칭을 모름) 것과...
사이사이 때를 뺴줄 칫솔입니다~
그리고 극세사같은 걸레가 되겠습니다. 요것도
키캡을 꺠끗이 딱아주기 위해 준비!
키캡을 다 분리하는데 걸린시간은.. 거의 어렴풋이
3시간 20분정도 걸렸던거 같네요..;
허리가 끊어 지는지 알았습니다.
키배열은 알고는 있지만~~
나중에 낄때 까먹을까바.. 나란히 정렬을
해놓고 작업을 했습니다.
정렬해놓은 상태에서 샷~ (때가 낀게 보이시죵)
클릭해서 보시면 저 지저분한 때들이 보이실 껍니다. (클릭안해도 잘보이네요.)
저것들을 칫솔을 이용하여 청소하였습니다.
짜잔~ 깨끗해 졌습니다. 정말 감동이였죠. 근데.. 다시 낄생각을 하니까.. OTL.....
키캡을 끼우기 전에 장난좀 쳐봤습니다. :)
제 아이디와 아러뷰~ 를 했었는데.. 아러뷰는... 키캡을 딱기전에 해서.. 키캡의 때가 나와서..
(진한색감이 좋아서 좀 진하게 해놨습니다. -.-;)
깨끗히 청소한다음에 찍은 키캡들~
휴.. 이제 다 키캡도 제자리로 놓았고.. 집에서는 그냥 IBM OEM 을 쓰고 있으니..
이건 일할때 까지 봉인해야겠습니다. 박스 닫기전에 샷~
이제 일하기 전까지는 봉인입니다. 안녕 나의 마제여~...
쿠키를 이용한 아이디 저장..
친구가 일하면서 나에게 숙제를 줘서.. 하다보니까 나중에 써먹을 일이 있을꺼 같아서..
대충 구현하고 포스팅~
------------------------------------------------------------------------------------------------
[code type=javascript]
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title>쿠키</title>
<script language="javascript">
//document.onreadystatechange=function(){
// if(document.readyState == "complete") chkCookie();
//}
function setCookie (name, value) {
if (confirm('ID를 저장하시겠습니까?'))
{
if (document.loginFrm.isCheck.checked)
{
var expdate = new Date();
expdate.setTime(expdate.getTime() + 1000 * 3600 * 24 * 7); var sTmpStr = name + "=" + escape (value) + "; expires=" + expdate;
document.cookie = sTmpStr;
//alert('쿠키값저장 = ' + sTmpStr); }
}
} function getCookie(Name) {
var search = Name + "="
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset)
if (end == -1)
end = document.cookie.length
return unescape(document.cookie.substring(offset, end))
}
}
return "";
}
function deleteCookie( cookieName ){
document.cookie = cookieName+"=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
location.reload();
} function chkCookie(){ var isCookie = document.loginFrm;
if (getCookie('uid') != "")
{
document.loginFrm.isCheck.checked = true;
document.loginFrm.uid.value=getCookie('uid');
}
else
{
document.loginFrm.uid.value='';
document.loginFrm.isCheck.checked = false;
}
}
</script>
</head>
<body onload="chkCookie();"> <form name="loginFrm" action="test1.html">
<input type="text" name="uid">
<input type="checkbox" onclick="javascript:setCookie('uid', document.loginFrm.uid.value);" name="isCheck"><br>
<input type="submit" value="확인">
<input type="button" value="삭제" onclick="javascript:deleteCookie('uid');">
</form>
</body>
</html> [/code]
2007년 4월 13일 금요일
Fujitsu LifeBook S7111SD20VP..
찜했으~~~~~ 완존 업무용~~ 디잔도 블랙~
해상도도 좋아~ 무게도 좋아~ 성능도 좋아~ 삼박자 두루두루~
.....근데 언제 사지 -_-