2021년 11월 9일 화요일

2021. 11. 09

 I submitted application documents for a daycare center today. The total number of applicants scheduled to be selected was 7, and I was the 11th applicant. In other words, the final successful candidates are selected through a lottery. It feels strange that this situation is happening to me, which I've only seen on the news.

2021년 11월 1일 월요일

2021. 11. 01

 I've been thinking that I won't be able to see retirees in this company. This is because the company guarantees the retirement age of employees to some extent. 

However, my thoughts were broken today. I was noticed that one in the same department wanted to leave the company, and the moment of separation would come earlier than I expect. 

At this moment, I am completely satisfied with my current work. But one day, I may also think about leaving the company.

2021년 4월 26일 월요일

우분투 Proxy 네트워크 환경에서의 apt-get 환경 설정 방법

회사 네트워크에 물려서 사용하다 보니 우분투 세팅에, 특히 네트워크 관련 모든 설정들이 엉망이다.
apt-get은 특히나 많이 사용되는 명령어인데, proxy 환경에서 사용하기 위해서는 설정 파일을 별도로 생성하여 설정해주어야 한다.

우선, /etc/apt/apt.conf 파일을 nano에디터를 사용해서 신규로 생성해준다.
(기존에 설정 파일이 있는 경우에는 그냥 그 파일을 오픈)

>> sudo nano ./apt.conf


Acquire::http::Proxy "http://Username:Password@proxy.foo.bar.edu.au:8080";
Acquire::ftp::Proxy "ftp://Username:Password@proxy.foo.bar.edu.au:8080";
Acquire::https::Proxy "https://Username:Password@proxy.foo.bar.edu.au:8080";

위의 내용을 작성 후 저장하면 완료!!!

마지막 부분에 세미콜론 잊지말것.

2021년 2월 15일 월요일

출근길 접촉사고 그리고 액땜

 나는 액땜이라는 말을 그렇게 즐겨 사용하지는 않는다.

그러나 주위에서 연말연시에 안좋은 일을 당한 지인에게 자주 했던 말이,

"그냥 액땜했다고 쳐".


그리고 그 일이 나에게도 벌어졌다. 음력 1월 1일... 설날 연휴를 잘 보내고 월요일 아침 출근을 서두르는데 잠시 딴생각을 좀 하다가... -_-


난 충분히 공간이 있다고 생각하고 머리부터 차를 천천히 집어 넣었으나....

차량 후미가 옆차선의 차량과 접촉하고 말았다.


나중에 블박 열어서 확인해보니 그 때 당시 나의 차량 속도는 6km/h 정도...

정말 서행이긴 했는데... 그래도 뭐 상대차량은 정차중이었고... 내가 가져다 긁었으니 일단 죄송하다고 사과하고 사진찍고 번호 교환 후 일단 출근을 했다.


그래도 하루종일 이 찜찜한 기분은 뭐지 -_-;;;


있을 수 있는 일이라고는 해도... 한순간의 실수로 인해 기분이 상하는건 어쩔 수 없나보다.

이런 일 거의 없었는데... 이번엔 나에게 이야기 해주어야겠다.

"액땜했다고 치고 올 한해 잘 지내보자"




2021년 2월 2일 화요일

고과 발표일

사실 직장 생활에 낙이랄게 뭐가 있겠나...

그저 매년 월급 오르는거랑.. 내가 1년 동안 했던 일에 대한 평가 잘 받고

그거 기반으로 진급하는거 아닐까.

오늘은 지금의 회사로 이직한 뒤, 첫 고과가 오픈된 날이었다.

 

사실 작년의 경우 입사 후 첫 해이기도 하고 분위기 파악도 할겸해서 뭔가 앞장서서 해보지는 않았다. 생각해둔 거의 대부분을 올해로 미뤄둔 상태였기에....

 

오늘 받은 고과에 딱히 불만이 있는 것은 아니었다.

 

다만 1년이라는 시간을 보내본만큼 앞으로 어떤 식으로 하면 되겠구나하는 막연한 짐작이 생겼을 뿐이지..

확실히 이 조직은 고과에 크게 연연하지 않는 분위기이다.

 

뭐 나 조차도 큰 관심은 없었으니....

 

올해는 예상하고 있는 실적들을 기반으로 작년보다 좀 더 나은 결과를 만들어 보도록 노력해봐야겠다.

2021년 1월 27일 수요일

코로나 시대와 새로운 취미

 코로나 바이러스가 우리의 일상을 점령하기 시작한지 어느덧 1년이 넘는 시간이 흘렀다.

여전히 하루에도 400~500명의 새로운 감염자가 뉴스의 첫 머리를 장식하는 요즘이다.

만약 우리 가정에 도현이와 같은 아기가 없었다면...

우리도 그저 똑같이 외식하고 여행가고 쇼핑하고 다녔을까? 그건 모르겠다.

다만, 지금 이제 막 두돌 지난 아기가 우리 집안에 있고 무서운 바이러스가 밖에서 퍼지고 있으니,

우리가 할 수 있는 일은 그저 외출을 자제하고 되도록이면 집에서 많은 활동을 하는 것이다.

그래서 생겨난 취미가 책읽기다.

풍부한 교양과 지식을 쌓을 수 있는 책이라면 더할나위 없겠지만... (사실 이런 책들은 이미 질려 버렸다)

그냥 무협지, 판타지, 그리고 만화책이 내 위안이요 휴식처가 되고 있는 요즘이다.

내가 중고등학교 다니던 시절에는 동네마다 책대여점이 널려 있었다.

만화책은 2~300원, 소설책은 700원 정도면 하루 이틀 대여해서 집에서 뒹굴거리며 읽기에 딱이었는데....

세월이 바뀌고 저작권법이 무서워지기 시작하면서 그런지 도서관 말고는 책을 빌릴 수 있는 곳이 전무하다. 대신 새롭게 유행하기 시작한게 당근마켓과 같은 지역 사회 기반의 중고거래 시장이다.

엄청나게 많은 사람들이 오늘도 중고 물품들을 어플에 등록하고 직거래를 통해 활발히 거래하고 있다.

여러 시대적 상황과 조건들이 잘 맞아떨어져서 예전 책대여점에서 빌려보던 가격으로,

비교적 깔끔한 소설책이나 만화책을 세트 단위로 중고로 구매해서 심심할때마다 잘 읽고... 다시 중고로 되
팔고 있다.

생각해보면 중고로 사서 중고로 다시 판매하니 내가 쓰는 돈도 거의 없는 셈이다.

며칠 전에는 중고로 만화책을 거진 30만원 가까이 주문해서 택배로 받았는데... 이게 박스로만 3박스 정도 되더만... 원피스 (어느샌가 97권까지 나왔더라) 전체 세트와 바람의 검심 세트... 내가 학창시절 읽기 시작하고 다 읽었던 만화책들인데...

그 뒤로 여러편이 더 나오기도 했고 때로는 다시 읽고 싶은 생각이 들기도 하고... 또는 나의 어렸을 적 추억
을 아들과 앞으로 공유하고 싶은 생각도 든다.

그래서 하나씩 사모으기 시작한게 어느덧 규모가 꽤 되었다. (아무래도 방에 책장을 크게 하나 들여야 할지도 모르겠다)

아무튼... 당분간은 이러한 취미 생활에 용돈을 꽤나 투자할 듯 하다.

지금은 나의 상황과 사회적인 시대 상황이 여러모로 잘 맞아 떨어지니깐!!



2021년 1월 26일 화요일

[MFC] 코드 실행 순서

응용프로그램이 시작되기 전에 프로그램이 사용할 메모리나 기타 실행에 필요한 기본적인 요건들을 운영체제가 할들. 그러한 작업이 완료되면 운영체제는 __WinMainCRTStartup() 코드를 실행한다. 이 함수에서는 전역 객체를 생성하고 실제 WinMain()을 호출한다.

 

여기서 말하는 전역 객체는 모든 프로젝트 생성시 하나 존재하는 theApp 객체이다. 이 객체는 CWinApp 클래스를 상속받은 CSDI_SequenceApp 객체이다.

 

WinMain()은 다시 AfxWinMain() 함수를 호출하게 되는데, 이 함수는 내부적으로 AfxInInit()함수를 호출하여 MFC 프레임 워크를 초기화하고, 우리 눈에 보이는 코드들이 실행에 들어간다.

 

CSDI_SequenceApp()

- 눈에 보이지 않는 코드들에 의해서 응용 프로그램 객체는 생성될 것이며 이 시점에서 응용 프로그램 객체의 생성자가 호출된다.


CSDI_ASequenceApp::InitApplication()

- MFC에서는 더이상 사용되지 않는 멤버 함수이다.


CSDI_SequelceApp::InitInstance()

- 응용 프로그램이 초기화 되는 부분이며, 이와 관련한 코드들이 집결되는 곳이다.

ex) 응용프로그램의 설정 정보 로딩(윈도우 크기, 옵션, 스타일 등)

스플래시 윈도우 초기화 (일반적으로 출력은 CMainFrame의 OnCreate() 함수)

응용 프로그램의 중복 실행 방지

트라이얼(Trial) 버전의 기간 검사 루틴

운영체제 버전 확인 및 프로그램 실행 여부 결정

프로그램 사용자 인증 (특정 사용자만 프로그램을 실행하도록 하고 싶은 경우)

프로그램 실행 시 인자로 전달되는 매개변수 처리

 

중요 맴버 함수 :
AddDocTemplate() - 도큐먼트 템플릿 객체를 응용 프로그램 객체에 등록한다
ParseCommandLine() - 매개 변수에 따라서 기본적인 명령을 수행하기에 앞서 내용을 분석
ProcessShellCommand() - 매개 변수로 전달된 프로그램 실행 옵션이나 열어야 하는 문서를 지정한 경우, 파일의 열기 혹은 빈 문서의 생성과 같은 작업을 실행 (ex 워드 파일을 더블클릭하면 자동으로 워드가 실행되어 파일을 로딩)

 

CSDI_SequenceDoc::CSDI_SequenceDoc()

- 도큐먼트 객체의 생성자를 호출하면 응용 프로그램 객체에 이어 두 번째로 생성된다. 중요한 것은 현재까지 사용자 인터페이스와 관련한 객체, 즉 윈도우 객체에는 아무 것도 생성되지 않았다.


CMAinFrame::CmainFrame()

- 응용 프로그램 인터페이스의 틀이 되는 프레임 윈도우 객체를 생성한다. 객체가 생성되었을 뿐, 아직 아무 것도 만들어지거나 나타나는 것은 없다.


CMainFrame::LoadFrame()

- CFrameWnd 객체가 생성된 후 이 응용 프로그램 윈도우와 관련한 메뉴, 가속기, 아이콘과 같은 리소스들을 로딩하고 윈도우를 생성한다. 아직 화면에는 어무 것도 보이지 않는다.


CMainFrame::PreCreateWindow()

- 윈도우가 생성되기 직전에 호출되는 함수이다.

이 함수의 역할 중 가장 중요한 것은 생성되는 윈도우의 스타일 정의 혹은 변경이다. 기본적으로 생성되는 윈도우는 아주 흔하게 볼 수 있는 모든 요소를 가지고 있따. 이러한 사항들을 변경하고자 한다면 인자로 전달된 CREATESTRUCT 구조체의 값을 변경하면 된다.

 

CMainFrame::PreSubclassWindow()

- 서브 클래싱 직전에 호출되는 함수. 서브클래싱이랑 윈도우 프로시저 함수를 따로 두는 것을 의미한다.


CMAinFrame::OnCreate() - Call

- WM_CREATE 메시지를 받았을 때 호출되는 메시지 핸들러이다. LoadFrame() 함수가 호출되면서 윈도우가 생성되고, 그 때 WM_CREATE 메시지는 자동으로 발생한다. 이 함수에서 하는 일은 CMainFrame 객체 내에 있는 몇몇 차일드 윈도우(툴바나 상태 표시줄 등)를 생성하는 일을 한다. 이 함수 내에서 상위 클래스의 OnCreate() 함수를 명시적으로 호출함으로써, 다른 함수들이 또 다시 호출된다.
1) CMainFrame::OnCreateClient() - Call

상위 클래스의 명시적 호출로 인해 호출되는 첫 번째 함수인데, 함수의 주된 역할은 클라이언트 뷰를 생성하는 일이다.
2) CSDI_SequenceView::CSDI_SequenceView()

클라이언트 뷰의 생성자가 호출된다.
3) CSDI_Sequence::Create() - Call

클라이언트의 윈도우를 생성한다. 그리고 이 함수의 호출결과로 아래 네 개의 함수들이 추가로 호출된다.
CSDI_Sequence::PreCreateWindow()

앞서 프레임 윈도우 생성시의 함수와 같은 역할이다.
CSDI_Sequence::PreSubclassWindow()

앞서 프레임 윈도우 생성시의 함수와 같은 역할이다.
CSDI_Sequence::OnCreate() - Called

클라이언트 뷰에 WM_CREATE 메시지가 전달되고, 그 메시지 헨들러가 호출된 것이다. 결국 각각의 윈도우는 자기만의 메시지 핸들러를 두게 되며, 자신에게 해당되는 메시지를 받아 처리한다.
CSDI_Sequence::OnCreate() - Return
CSDI_Sequence::OnShowWindow() - Call
윈도우가 화면에 나타나거나 사라질 때 호출된다. 좀 더 정확히는 WM_SHOWWINDOW메시지에 대한 핸들러이다.

CSDI_Sequence::OnShowWindow() - Return


CSDI_Sequence::Create() - Return

- 클라이언트 뷰 윈도우의 생성이 완료되었다.


CMainFrame::OnCreateClient() - Return

- 프레임 윈도우는 클라이언트 뷰를 생성하는 작업을 끝냈다.


CMAinFrame - m_wndToolBar.CreateEx
CMainFrame - m_wndStatusBar.Create
CMainFrame::OnCreate() - Return

 

CSDI_Sequence::OnNewDocument() - Call

- 현재 프로그램이 실행될 때 엑셀이나 워드처럼 응용 프로그램과 연결된 데이터 파일을 오픈한 경우가 아니므로 빈 문서, 즉 새 문서를 연다. 관련된 것이 없다고 하더라도 SDI구조를 가졌기 때문에 내부적으로 문서를 만든다.

CSDI_Sequence::OnNewDocument() - Return


CSDI_Sequence::OnInitialUpdate() - Call

- 클라이언트 뷰의 생성이 완료되면 응용 프로그램의 프레임 윈도우는 자신의 클라이언트 뷰에 WM_INITIALUPDATE 메시지를 보내게 되고, 그 메시지를 받은 클라이언트 뷰는 이 메시지 핸들러를 호출한다.이 함수는 매우 중요하다. 이 메시지 핸들러는 새로운 문서가 열릴 때마다 호출된다. 그러나 응용 프로그램과 연결된 문서가 존재하지 않고 파일을 열 일이 없다면, 딱 한번만 수행될 것이다.
CSDI_Sequence::OnInitialUpdate() - Return

 

* 초기화 완료 ==============================

CMainFrame::OnActivateApp() - Call
CMainFrame::OnActivateApp() - Return
CMainFrame::OnActivate() - Call
CMainFrame::OnActivate() - Return

초기화가 완료된 후, 응용 프로그램은 활성화되어 모니터 화면의 맨 위로 나타나게 될 것이다. 두 함수는 화면에 응용 프로그램이 나타나는 것 까지로 보면 된다.


CMainFrame::OnShowWindow() - Call
CMainFrame::OnShowWindow() - Return

응용 프로그램이 활성화되고 프레임 윈도우가 화면에 나타나게 된다. 작업 표시줄에 자신의 항목도 하나 생겼을 것이고 모니터 화면에서 맨 위에 보여질 것이다.


### CSDI_SequenceApp::Run() - Call ###

메시지 루프를 시작하는 함수이다. 결국 이 함수는 내부적으로 ::PeekMessage() 함수를 호출하여 자신에게 메시지가 있는지 검사를 한다. 만일 처리할 메시지가 없다면 사용자가 입력을 받거나 혹은 마우스 이벤트가 발생한다거나 하는 일이 없다는 것이다.

 

하나의 메시지를 처리하는 세 가지 방법이 있다. 첫 번째는 CMainFrame의 WindowProc() 함수에 코드를 추가하는 것이고, 두 번째는 CMainFrame의 OnCreate() 메시지 핸들러 아래에 코드를 추가하는 것이다. 마지막으로 CMainFrame의 PreTranslateMessage() 멤버 함수에 코드를 추가하는 방법이다.  이 함수는  TranslateMessage() 함수가 호출되기 전에 호출된다. 즉 메시지 큐에서 메시지가 꺼내지고 해석되기 전에 호출되는 함수이다.

 

* 응용 프로그램 종료 ==============================

CMainFrame::OnClose() - Call

- 닫기 혹은 Alt+F4를 입력하면 WM_CLOSE 메시지가 발생한다. OnClose() 함수는 WM_CLOSE 메시지에 대한 핸들러이다. 이 함수가 리턴하기 전에 내부적으로 아래의 함수가 이어서 호출된다.
CMainFrame::OnShowWindow() - Call
CMainFrame::OnShowWindow() - Return
CMainFrame::OnActivate() - Call
CMainFrame::OnActivate() - Return
CMainFrame::OnActivateApp() - Call
CMainFrame::OnActivateApp() - Return

자원의 반납이나 차일드 윈도우의 내용을 저장하는 것 정도의 코딩을 한다.


CMainFrame::DestroyWindow() - Call

OnClose() 함수는 실제로 윈도우를 파괴하기 위해서 이 함수를 호출하게 되는데 이 함수가 호출되고 나면 윈도우가 파괴되므로 그 전에 차일드 윈도우를 모두 파괴하여야 한다. 이를 알리기 위해서 내부적으로 WM_DESTROY와 WM_NCDESTROY 메시지가 연이어 전달된다. WM_DESTROY는 윈도우 전체가 파괴되는 신호라면 WM_NCDESTROY는 프레임의 테두리가 파괴되는 신호이다.


CMainFrame::OnDestroy() - Call
CMainFrame::OnDestroy() - Return
CSDI_Sequence::OnDestroy() - Call
CSDI_Sequence::OnDestroy() - Return
CSDI_Sequence::PostNcDestroy() - Call
CSDI_SequenceView::~CSDI_SequenceView()
CSDI_Sequence::PostNcDestroy() - Return
CMainFrame::PostNcDestroy() - Call
CMAinFrame::~CmainFrame()
CMainFrame::PostNcDestroy() - Return


CMainFrame::DestroyWindow() - Return

응용 프로그램의 최상위 부모 윈도우인 메인 프레임 윈도우가 완전히 파괴되었다.
CSDI_SequenceDoc::~CSDI_SequenceDoc()

화면상에 나타나는 사용자 인터페이스, 즉 윈도우 객체들이 모두 파괴된 후 관련된 도큐먼트 객체가 소멸된다.

 

CMainFrame::OnClose() - Return

- 클라이언트 뷰, 도큐먼트 객체 뿐만 아니라, 자신도 이미 파괴되었다. 이제 남은 것은 응용프로그램이 사용한 자원들을 반납하는 것 뿐이다.


CSDI_ASequenceApp::ExitInstance()

- 모든 객체들이 소멸한 가운데, 응용 프로그램의 최종 종료에 앞서서 마지막으로 호출되는 함수이다. 따라서 이 함수에는 응용프로그램의 설정을 저장한다거나, 중복 실행 방지를 위해 획득했던 시스템 리소스를 반납한다거나, 메모리를 해제하는 등 최종 마무리 작업을 해야 한다.


### CSDI_SequenceApp::Run() - Call ###
- Run()의 리턴은 메시지 루프의 종료를 의미하므로 프로그램이 최종 종료되는 것이다. 이 과정에서 우리 눈에 보이지 않는 코드가 실행되는데, AfcWinInit와 반대로 AfxWinTerm() 이라는 함수가 수행되어 초기화했던 MFC 라이브러리를 해제한다. 

2021년 1월 15일 금요일

헝가리안 표기법(Hungarian Notation)

10, 15년전 Microsoft의 개발자 중 헝가리 사람의 프로그래머가 쓰던 변수 명명법.

MS 내부에서 따라 쓰기 시작하던 것이 점차 전세계의 프로그래머들에게 널리 퍼져 이젠 프로그램 코딩시 변수 명명의 표준적인 관례가 되었다. 그러나 실제로 현장에서 일하다 보면 헝가리안 표기법을 제대로 지키는 개발자는 그리 많지 않다. 어느 정도 개발 경험을 가지고 있는 프로그래머는 물론 심지어 시중의 프로그래밍 서적에서 조차 저자마다 변수명을 개인에 따라 가지각색으로 짓고 있어서 처음 프로그램을 배우는 입문자들이 변수 명명에 대한 기준을 제대로 잡지 못하고 있는 실정이다.

그러나 변수 명명에 관한 표준화된 관례를 지켜주면 코드의 가독성을 높여줄 뿐만 아니라 예를 들어 카운터 변수를 count라고 지을지 cnt라고 지을지 고민하지 않아도 되는 편리함을 누릴 수 있다.

Prefix

Data Type

Description

Example

b

BOOL

any boolean type

BOOL bTrue;

c

char

character type

char cLetter;

i

int

integer for index

int iCars;

n

int

number, quantity

int nNum;

l

long

long type

long lDistance;

u

unsigned

unsigned type

unsigned uPercent

f

float

floating point

float fPercent;

d

double

double floating point

double dPercent;

w

WORD

unsigned word

WORD wCnt

dw

DWORD

unsigned double word

DWORD dwLength

p

*

any pointer

int *piAddr;

pfn

*

function pointer

int (*pifnFunc1)(int x, int y);

rg, a

array

stands for range

float rgfTemp[16];

sz

*

Zero-terminated string of characters

char szText[16];

s

static

a static variable

static short ssChoice;

t

struct

a user defined type

 

e

enum

variable which takes enumerated values

 

E

enum

Enumerated type

 

g_

Global

Global Variable

String *g_psBuffer;

m_

Member

class private member variable

int m_iMember;

k

constant formal parameter

...

void vFunc(const long klGalaxies)

r

reference formal parameter

...

void vFunc(long &rlGalaxies)

prg

...

dynamically allocated array

char *prgGrades;

v

Void

 

 

x/y

...

used as size

int xWitdth, yHeight;

h

handle

handle to something

hMenu

 

 

Format

x_xXxxxxxx

0123456789

0 : 변수의 위치를 지정한다. g(전역변수), m(멤버변수), 없음(지역변수)
1 : 0 위치에 g 나 m 을 지정한 경우 _ 을 기술한다.
2 : 자료형의 종류를 나타낸다.

3 ~ : 변수의 의미 있는 이름을 기술하며, 3 위치는 대문자를 사용한다. 변수 이름이 너무 긴 경우 자음만을 기술한다. 예) g_nCnt

 

Example of type specific variable naming

int g_nCnt                              :정수형 글로벌 카운터
unsigned char ucByte;            :한 바이트 데이타 
         char cChar;                  :한 문자 
unsigned char rgucByte[10];   :바이트 데이타 10개 
         char rgcChar[10];         :문자 데이터 10개
         char szChar[16 +1];      :문자 16개를 저장할 수 있는 문자열 공간