C# & VB.NET2006. 3. 11. 22:55
물론 C#에서는 Base64 인코딩, 디코딩 API가 있지만,
공통 함수로 다음과 같이 만들고 쓰면 편하다.
두 줄이라도 공통화시키고, 또 string을 넘겨서 string을 받으니 직관적이기도 하다.

public static string Base64Encode(string src, System.Text.Encoding enc)
{
  byte[] arr = enc.GetBytes(src);
  return Convert.ToBase64String(arr);
}

public static string Base64Decode(string src, System.Text.Encoding enc)
{
  byte[] arr = Convert.FromBase64String(src);
  return enc.GetString(arr);
}  
Posted by kkongchi
C# & VB.NET2006. 3. 11. 22:48

private void WriteTempLog(string contents)
{
string strFileName = "c:\\Navigator.txt";
System.IO.FileStream oFS = null;
System.IO.StreamWriter oSW = null;
string strLogContents = "";


  try
{
  //파일스트림 객체 초기화
  oFS = new System.IO.FileStream(
   //파일 이름 지정
    strFileName,
   //파일이 있으면 열고, 없으면 만든다
    System.IO.FileMode.OpenOrCreate,
   //파일을 읽기,쓰기 모드로 연다
    System.IO.FileAccess.ReadWrite);


   //스트림라이터 객체 초기화
   oSW = new System.IO.StreamWriter(oFS);


   //마지막 부분을 찾는다.
   oSW.BaseStream.Seek(0, System.IO.SeekOrigin.End);


   strContents = contents;

   oSW.Write(strContents);


   //반드시 flush를 해야, 메모리에 있는 내용을 파일에 기록한다.
  //flush하지 않으면 파일을 잠그기 때문에 다른 프로세스가 이 파일에 접근할 수 없다
   oSW.Flush();
  oSW.Close();
}
catch(Exception ex)
{
  throw ex;
}
finally
{
  oSW = null;
  oFS = null;
}

Posted by kkongchi
javascript & HTML2006. 3. 11. 15:05

javascript에는 Left, Right 함수가 없다.. 하지만, 코딩하다보면 필요한 때가 가끔..있다..

http://www.devx.com/tips/Tip/15222 - 요 사이트에서 찾았다.
당연히 저작권은 devx 와 article의 저자에게..

  1. function Left(str, n){
  2. if (n <= 0)
  3.   return "";
  4. else if (n > String(str).length)
  5.   return str;
  6. else
  7.   return String(str).substring(0,n);
  8. }
  9. function Right(str, n){
  10.   if (n <= 0)
  11.      return "";
  12.   else if (n > String(str).length)
  13.      return str;
  14.   else {
  15.      var iLen = String(str).length;
  16.      return String(str).substring(iLen, iLen - n);
  17.   }
  18. }
 
Posted by kkongchi
javascript & HTML2006. 3. 10. 17:35

아래 코드는 XmlHttp를 사용해서, 웹 페이지를 Post 방식으로 호출하는 아주 간단한 코드이다.

이런 방식을 사용해서

웹사이트 자동 로그인을 한다거나(아래 코드처럼),

혹은 웹 페이지의 특정 데이터를 Scrapping해올 수 있다.


var xml;

xml = new ActiveXObject('Microsoft.XMLHTTP');

xml.Open("POST", "http://www.test.com/login.aspx", false);

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

xml.Send("id=kkongchi&pw=kkongchipw");


Get방식을 사용할 때는 이렇게...


var xml;

xml = new ActiveXObject('Microsoft.XMLHTTP');

xml.Open("GET", "http://www.test.com/data.aspx?id=1", false);

xml.Send();

Posted by kkongchi
Software Engineering2006. 3. 6. 02:51
The Joys of Programming(프로그래밍의 기쁨)
-"The Tar Pit", "Mythical Man-Month (Fred Brooks)" 중에서


왜 프로그래밍이 즐거운가? 어떤 기쁨이 프로그래머를 기다리고 있는가?

첫번째로는 무언가를 만드는 기쁨이 있다. 아이가 진흙으로 파이를 만들면서, 어른들이 무언가를 만들면서(특히 자신의 디자인으로) 기뻐하는 것과 같다. 이 기쁨은 아마도 조물주의 기쁨과 비슷한 것일꺼라 생각하는데, 각각의 잎새나 눈송이의 새로움과 독특함에서 우리가 엿볼 수 있는 그런 기쁨이다.

두번째는 다른 사람에게 유용한 무언가를 만들었을 때의 기쁨이다. 마음 깊은 곳으로부터, 우리는 우리가 만든 것을 다른 사람이 사용하고 그것이 유용하길 바란다. 이런 관점에서 본다면 프로그래밍은 아이가 첫번째로 만든 찰흙 연필 꽂이("아빠 사무실 용")과 다르지 않다.

세번째는 복잡한 퍼즐을 풀어서 그것이 처음에 만들어졌던 원리에 따라서 움직이는 것을 보는 즐거움이다. 프로그래밍된 컴퓨터는 핀볼 기계나 쥬크박스가 가지고 있는 모든 매력을 가지고 있으며, 그러한 매력의 극한을 보여준다.

네번째로는 항상 배워나가는 즐거움이 있다. 항상 새로운 문제들이 나오고, 그것을 풀면서 우리는 새로운 것(때로는 실용적인, 때로는 이론적인, 가끔은 양쪽 모두인)들을 배우게 된다.

마지막으로, 뭔가 마음대로 할 수 있는 것을 가지고 일하는 즐거움이 있다. 프로그래머는 마치 시인처럼 순전히 머리 속에 있는 것들 사이에서 이동하며 일한다. 프로그래머는 허공에 성을 세우고, 그 허공에서부터 상상력을 발휘한다. 다른 창조의 작업들은 이것만큼 유연하지도 않고, 허물고 다시 만들기도 쉽지 않으며, 그래서 거대한 개념 구조를 만들기도 쉽지 않다.
그러나 프로그램이 만들어지면, 시인의 시와는 달리 실제적인 모습을 드러낸다. 프로그램은 결과를 출력하기도 하고, 그림을 그리기도 하고 소리를 만들어내기도 한다. 신화와 전설의 마법이 우리 시대에 출현한 것이다. 누군가가 키보드로 정확한 주문을 입력하면 스크린이 현실에 전에 없었던 것들을 보여주는 것이다.

프로그래밍은 우리 내부의 깊은 곳에 있는, 그리고 모든 인간이 갖고 있는 창조의 욕망을 만족시킨다는 점에서 정말로 재미있다.  
Posted by kkongchi
Software Engineering2006. 3. 6. 02:50
The Woes of Programming
-"The Tar Pit", "Mythical Man-Month (Fred Brooks)" 중에서

첫번째로 우리는 완벽하게 수행해야 한다는 점이다. 컴퓨터는 이런 점에서 전설의 마법들과 유사하다. 만약 마법사가 주문을 제대로 외지 못하면 마법은 실패하게 된다. 인간이란 존재는 완벽함에는 익숙하지 않고, 인간의 활동 중에서 완벽함을 요하는 것은 극히 드물다. 완벽해야 한다는 요구 사항에 맞추는 것이 내 생각으로는 프로그래밍의 가장 힘든 부분이 아닐까 한다.

다음으로 다른 사람들이 프로그래머에게 목표를 주고, 리소스를 제공하며 정보를 제공한다는 점이다. 프로그래머는 그의 작업환경이나 심지어 목표마저도 자신이 컨트롤할 수 없다. 관리의 측면에서 보면 프로그래머의 권리는 그의 책임에 비해서 충분치 못하다. 그러나, 다른 분야에서도 일을 끝내는 사람들의 형식적인 권리는 그 책임에 비해서는 사실 적당치 않다. 실제로 실질적인 권리는 목표를 달성한 바로 그 힘에서 얻어진다.
다른 사람에 대한 의존은 특히 시스템 프로그래머에게 고통이 된다. 그는 다른 사람의 프로그램에 의존해야 한다. 그것들은 간혹 제대로 디자인되어 있지 않으며, 아주 형편없이 구현되어 있고, 불완전하게 배포되어 있고 거의 문서화되어 있지 않다. 그래서 그는 이상적인 세계에서라면 완전하고 사용할 수 있었어야 하는 것들을 시간을 들여서 연구하고 고치게 된다.

다음으로, 커다란 컨셉을 디자인하는 것은 재미있는데, 작은 버그를 찾는 것은 단지 일일뿐이라는 사실이다. 언제나 창조적인 활동의 뒤에는 따분하고 고통스러운 노동이 따라오는데, 프로그래밍도 예외가 아니다.

또 다음으로는 프로그래머는 디버깅은 계속해서 수렴되는 성질을 갖고 있어서, 하나씩 처리할 때마다 노력이 두배씩 계속 늘어나는 방식의 접근을 계속 해야만 하는 그런 작업이라는 것을 알게 된다는 것이다. 그래서 테스트는 계속 되고, 마지막의 가장 어려운 버그는 처음 것을 찾을 때보다 더 많은 시간이 들게 된다.

마지막으로 프로그래머가 오랫동안 열심히 만든 소프트웨어가 완성 직전에 보니 너무 낡아보인다라는 점이다. 이미 동료나 경쟁자들은 새롭고 더 나은 아이디어를 쫓아가고 있다. 이미 프로그래머가 가진 생각에서 뻗어나온 대체물들은 생각의 차원을 넘어서 만들어지고 있는 중인 것이다.
실제로는 그렇지 않다. 새롭고 더 나은 프로덕트들은 대체로 프로그래머가 자신의 것을 완성했을 때에는 절대로 나오지 못한다. 그냥 아직은 단지 얘기되고 있을 뿐이다. 그리고 만들려면 몇개월의 시간이 필요하다. 진짜 호랑이는 종이 호랑이와는 상대가 되지 않는다. 실제로 존재하고 있다는 것이 중요하다.
물론 우리가 뭔가를 만드는 기술적인 기반은 항상 진보하고 있다. 우리가 디자인을 마쳤을 때, 그것은 개념적으로만 본다면 이미 낡은 것이다. 그러나 실제 프로덕트의 구현은 실질적인 작업을 필요로 한다. 구현된 제품이 낡았는지의 여부는 실재화되지 않은 개념보다는 다른 존재하는 프로덕트들과 비교해야 한다. 현실의 문제에 대한 실질적인 솔루션을 가능한 스케줄과 사용 가능한 리소스로 찾아내는 것이 진정한 도전이며 임무이다.  
Posted by kkongchi
Software Engineering2006. 3. 6. 02:47
1. 외부로부터 들어오는 모든 데이터를 검사하라
2. 루틴의 모든 매개변수 값을 검사하라

3. 잘못된 입력을 어떻게 처리할지 결정하라


이상은 스티브 맥코넬의 "Code Complete 2nd Edition"에서 제안하는 방어적 프로그래밍의 원칙이다.

나도 코딩을 하지만, 사실 일부러 신경쓰지 않는다면, 그리고 프로젝트에서 표준이 제공되지 않으면 잘 안하게 되는 경향이 있다. 하지만 최근 보안이 중시되는 경향을 감안한다면 어떤 프로그램을 만들더라도 반드시 이런 처리를 해줘야 한다. 이런 처리를 반드시 하는 코딩 습관을 만든다면 더욱 좋을 것이다.

또, 검사를 하더라도 아주 기본적인 검사만 하는 경우가 대부분이다..(저도..^^;;)
최근의 악의적인 코드나 공격등을 보면, 아주 엄격하게 검사를 하는 편이 좋다.
특히 DOS(서비스 거부)의 버퍼 오버 플로우 공격의 경우 아주 많은 양의 매개변수를 입력해서 프로그램을 공격한다. 그러므로, 받는 모든 변수의 NULL 여부 뿐만이 아니라 더 엄격하게 사이즈나 값의 범위 등을 모두 검사를 하는 것이 좋다. 가장 좋다고 생각되는 것은 프로그램에서 받을 수 있는 범위 외의 모든 값은 모두 거부하는 것이다.
Posted by kkongchi
Software Engineering2006. 3. 6. 02:44

소프트웨어 공학의 장기 베스트 셀러인 "Mythical Man-Month" 의 일부분이다. 20년전 책인데, 왜 아직도 이런 지적이 유효한 것일까....-_-;;;;;

Good Cooking takes time. If you are made to wait, it is to serve you better, and to please you.

-MENUS OF RESTAURANT ANTOINE, NEW ORLEANS

훌륭한 요리는 시간이 걸립니다. 만약 당신이 기다리고 있다면, 그건 당신을 더 잘 모시기 위해서, 당신을 기쁘게 하기 위해서입니다.

-뉴올리언즈 안트완 식당의 메뉴

Most Software projects have gone awry for lack of calendar time than for all other causes combined. Why is the cause of disaster so common?

대부분의 소프트웨어 프로젝트는 모든 다른 이유보다도 일정의 부족으로 인해서 실패한다. 왜 이런 비극이 자주 일어나는 것일까?

First, our techniques of estimating are poorly developed. More seriously, they reflect an unvoiced assumption which is quite untrue, i.e., that all will go well.

첫째, 우리가 가지고 있는 일정 추정 기술이 아직 보잘것없기 때문이다. 더 진지하게 말하자면, 전혀 말도 안되는 가정, 이를테면 "다 잘되겠지" 등등에 기반하고 있고 있기 때문이다.

Second, our estimating techniques fallaciously confuse effort with progress, hiding the assumption that men and months are interchangeable.

두번째, 우리의 추정 기법은 불합리하게도 일정상의 진전(Progress)과 공수(Efforts)을 혼동하는데,  인원과 기간을 바꿔가면서 쓸 수 있다는(즉 기간이 모자라면 인원을 더 늘리면 된다는) 가정을 숨기고 있다.

Third, because we are uncertain of our estimates, software managers often lack the courteous stubbornness of Antoine's chef.

세번째, 추정에 확신이 없기 때문에 매니저들은 때로 안트완 식당의 예와 같은 완고함을 잃어버린다.

Fourth, schedule progress is poorly monitored. Techniques proven and routine in other engineering disciplines are considered radical innovations in software engineering.

네번째, 일정에 따른 경과가 제대로 모니터링되지 않는다. 다른 공학분야에서 검증되고 확립된 모니터링 기술들도 소프트웨어 공학에서는 아주 과격한 혁신으로 받아들여진다.

Fifth, when schedule slippage is recognized, the natural (and traditional) response is to add manpower. Like dousing a fire with gasoline, this makes matter worse. More fire requires more gasoline, and thus begins a regenerative cycle which ends in disaster.

다섯번째, 일정이 지연되었을 때, 대부분의 전통적인 반응은 인력의 추가이다. 그런데 이는 불에 가솔린을 끼얹는 것처럼 상황을 더 악화시킬 뿐이다. 더 큰 불이 더 많은 기름을 요구하는 것처럼 결국 실패로 끝나게 될 또 하나의 사이클을 시작시킬 뿐이다.

Posted by kkongchi
C# & VB.NET2006. 3. 5. 17:56

C#에서는 try-catch-finally 구조를 사용해서 각 예외처리를 수행한다. 그런데 이 구조에서 예전에 제가 C#을 처음 익힐 때부터 약간 혼란스러웠던 것이 있다.


바로 Return 문이 어디에 위치해야 하는가이다...


MSDN 라이브러리의 try-catch-finally 구조에 대한 설명을 보자.

A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.

Catch finally같이 때의 일반적인 사용법은 try 블록에서 리소스를 얻어내서 사용하고, catch 블록에서는 예외적인 상황을 다루며, finally 블록에서리소스를 해제한다.



즉, return을 어디 두어야 하는 지는 어디에도 없다.

샘플도 교묘하게 void를 리턴 하는 함수를 만들어서 피해가고 있다.


두 가지 가설이 있을 수 있다.

첫 번째는 return은 메서드가 최종적으로 결과를 돌려주는 것이므로, finally 아래에 와야 한다.

두 번째는 try-catch-finally의 구조로 볼 때, return 문은 예외 처리 코드도 아니고 리소스 해제 코드도 아니기 때문에 try 내부에 오는 것이 맞다.

그래서 가지 방법으로 코드를 작성해 보았다.


//return문이 가장 마지막에 위치

public int ReturnInLastLine()

{

int i = 0;

PrivateOBJ obj = null;

try

{

obj = new PrivateOBJ();

i = obj.GetINT();

}

catch(Exception ex)

{

throw ex;

}

finally

{

obj = null;

}

return i;

}

//try블록 내부에 return이 위치

public int ReturnInTry()

{

int i = 0;

PrivateOBJ obj = null;

try

{

obj = new PrivateOBJ();

i = obj.GetINT();

           return i;

}

catch(Exception ex)

{

throw ex;

}

finally

{

obj = null;

}

}

그리고, 클래스를 컴파일한다음  .NET Reflector디스어셈블한 코드를 보았다.



결과는놀랍게도,

public int ReturnInLastLine()
{
int num1 = 0;
PrivateOBJ eobj1 = null;
try
{
eobj1 = new PrivateOBJ();
num1 = eobj1.GetINT();
}
catch (Exception exception1)
{
throw exception1;
}
finally
{
eobj1 = null;
}
return num1;
}

public int ReturnInTry()
{
int num2;
int num1 = 0;
PrivateOBJ eobj1 = null;
try
{
eobj1 = new PrivateOBJ();
num1 = eobj1.GetINT();

//여기 주의

//원 소스 코드에는 여기에 return이 있다. 그런데?
num2 = num1;
}
catch (Exception exception1)
{
throw exception1;
}
finally
{
eobj1 = null;
}

//여기에 리턴문이 있다.
return num2;
}


IL 코드도 이와 거의 유사하다고 보면 된다.

즉, return을 어느 위치에 두던지 간에 실제로 IL로 컴파일된 코드에서는 return이 가장 마지막에 위치한다는 것이다.

그래서 두 번째 try 내부에 리턴이 있는 경우를 보면 IL 코드는 내부적으로 (코드에는 없는) 변수를 하나
더 선언해서
거기에 값을 할당하고 그 변수를 최종적으로 리턴을 수행할 때 사용하는 것을 볼 수가 있다.



결론

1. 코드 상에서 return문이 어디에 있더라도, IL 코드 상에서는 가장 마지막 라인에 return문이 있게 된다. 결론적으로 마지막에 두는 것이 맞다는 것이다.

2. 코드에 Try 블록 혹은 catch 블록 혹은 여러 군데에 return을 위치시킬 수 있다. 심지어 if-else 문을 사용해서 각각 return하는 경우도 있다. (절대로 권장하지 않는 코딩방법!!) 그 경우 IL이 내부적으로 최종 리턴을 위해서 변수를 하나씩 더 할당한다. 이 값이 만약 매우 큰 데이터셋이라면? 메모리 누수의 원인이 될 수도 있을 듯 하다. 결과적으로 비효율적인 코드라는 것이고, 피해야 할 코딩이 되는 것이다.

Posted by kkongchi
Software Engineering2006. 3. 5. 00:45

스티브 맥코넬의 SPSG(Software Project Survival Guide)에 나오는

"생존 테스트" 이다.

소프트웨어 개발에 몸담고 계시는 분들은 한번씩 해보고

자신이 속한 프로젝트가 과연 살아남을 수 있을까 고민해보시는 것도 좋을 듯 하다.


1. Requirements

1.1. 프로젝트에 명확한 Vision 혹은 Mission 이 있는가?

1.2. 프로젝트 팀원 모두가 제시된 비전을 현실성있다고 생각하는가?

1.3. 고객이 그 프로젝트의 성공으로 얻게 될 비즈니스적인 이점과 그것에 대한 측정방법이 기술되어 있는 Business Case가 있는가?

1.4. 실제 시스템이 가지는 기능을 명확하게 보여줄 User Interface Prototype이 있는가?

1.5. Software Specification 은 상세하게 문서화되어 있는가?

1.6. 팀원들이 프로젝트 초기에 실제 사용자들과 미팅을 했는가? 또 실제 사용자들이 프로젝트에 지속적으로 참여하는가?

2. Planning

2.1. 소프트웨어 개발 계획이 문서화되어 있는가?

2.2. 작업 리스트에 인스톨러 개발, 이전 버전의 데이터 마이그레이션, 고객과의 회의 등 사소한 일까지 포함되어 있는가?

2.3. 일정과 예산 추정치를 최근에 공식적으로 업데이트했는가?

2.4. 아키텍처와 설계를 상세하게 문서화했는가?

2.5. 시스템 테스트, 코드 리뷰를 포함하는 상세한 품질 보증 계획이 문서화되어 있는가?

2.6. 각 단계별로 어떤 버전이 구현되고 납품되는지 상세히 설명한 단계별 납품 계획이 있는가?

2.7. 프로젝트 일정에 휴일, 휴가, 병가, 교육 등의 기간이 모두 포함되어 있는가? 또 인원 할당은 100퍼센트가 안되도록 버퍼가 잡혀있는가?

2.8. 일정을 포함한 모든 계획은 개발팀, 품질 보증팀 등의 모든 관련된 사람들의 승인을 받았는가?

3. Project Control

3.1. 권한이 있는 임원 한명이 프로젝트를 책임지는가? 그리고 그 임원은 프로젝트를 적극 후원하는가?

3.2. PM이 프로젝트에 몰두할 여건이 되어 있는가?

3.3. 프로젝트의 진척 여부를 파악하기 위한 상세한 마일스톤이 정의되어 있는가?

3.4. 프로젝트 이해 관계자들이 마일스톤의 달성 여부를 쉽게 파악할 수 있는가?

3.5. 팀원들이 무기명으로 상급자들에게 문제를 보고할 수 있고, 그 결과를 피드백 받을 수 있는가?

3.6. Software Specification의 변경을 통제하는 계획이 문서화되어 있는가?

3.7. 변경 요청 사항을 수용하거나 거부할 수 있는 권한을 가진 변경 통제 위원회(Change Control Board)가 구성되어 있는가?

3.8. 작업량, 예상 일정, 업무 분장, 계획 대비 진도 등의 현황을 모든 팀원들이 알 수 있는가?

3.9. 소스 코드의 버전 통제는 자동화되어 있는가?

3.10. 버그 트래킹, 소스 코드 통제, 프로젝트 관리 소프트웨어 등 프로젝트 수행 환경에 대한 기초적인 자동화 도구가 준비되어 있는가?

4. Risk Management

4.1. 프로젝트를 완료하는 데 필요한 모든 기술력을 확보했는가?

4.2. 팀원들은 소프트웨어가 운영될 업무 환경에 대한 전문지식을 보유하고 있는가?

4.3. 프로젝트를 이끌 기술 리더가 있는가?

4.4. 인력 자원은 충분한가?

4.5. 팀워크는 좋은가?

4.6. 팀원들이 프로젝트에 전념하고 있는가?




점수 계산 방법

-- 예비 점수: 각 항목별 점수 합산

-- 규모 가중치: 프로젝트 팀에 개발책임자, 품질 보증팀 리더, 최종 책임자를 포함하는 전담 인원이 3명 혹은 그 이하에는 1.5, 4-6명일 때는 1.25, 그 외에는 1.0

-- 최종 점수: 예비 점수 * 규모 가중치


점수에 따른 해석

90점 이상: 성공이 보장되는 프로젝트

80-89: 평균보다 훨씬 좋다. 일정, 예산, 품질 목표에 근접하게 소프트웨어를 납품할 확률이 매우 높다.

60-79: 평균보다 조금 나은 정도. 일정이나 예산을 충족시킬 확률이 어느 정도 있으나 두 가지를 모두 충족시키기는 어렵다.

40-59: 일반적인 수준. 상당한 수준의 스트레스와 불안한 팀워크를 경험할 확률이 높으며, 결국 비용 초과와 일정 지연으로 기대보다 품질이 떨어지는 소프트웨어를 납품하게 될 것이다.

40미만: 모든 부분이 취약하다. 프로젝트를 끝내는 것이 최대 목표가 된다.

Posted by kkongchi