[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

!!!사람을 힘들게 하는 것은 "Hard work"가 아니다. "Stress"다
사람들이 일을 즐기면 - 즐기지는 못하더라도 할만하면 -, 열심히 일해도 힘들지 않다.
그러나, 사람들은, 자신이 무엇을 하고 있고, 왜 이 일을 하고 있는지 알지 못하면 일을 즐길 수가 없다.
사람들은 자신이 하고 있는 일의 방향과 타당성을 알고 비젼에 공감하며, 열심히 일한 것에 대한 보상이 있을때, 일을 즐길 수 있고, 이때는 하루에 10시간 혹은 12시간을 일하더라도, "회사일 때문에 힘들다."라는 이야기를 하지 않을 수 있다.

반면, 내 경력에 전혀 도움이 되지도 않고, 왜 이 일이 필요한지도 모르겠는 일을 계속해서 하면서, 다른 사람과의 갈등으로 계속해서 스트레스를 받으면, 아무리 9-6 8시간 근무를 하더라도.."회사일 때문에 힘들다."라는 생각이 들 수 밖에 없다.

음.... 지금 당연한 이야기를 하고 있는 것일 수도 있으나.. 다시 한 번 되새겨 보자는 의미에서 한번 적어 본다....

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Before developing something, we should clarify "what we want to develop". In the same context, we want clear requirement specification. But I am not saying about requirement specification. Subject of this article is "Clear description about outcome - not only final one but also intermediate and sub-module's one". In case of very short and simple program, required goal is also simple and clear. So we don't need to worry about this. But, usually, size of software project is quite big.

Here is very big-size-software project. So, we divide a project into several sub-projects and assign these to sub-team; After developing each sub-project, we try to integrate them. But, as you know, integration is not an easy job. There may be conflicts between sub-module, interface mismatching and so on. Changing software design or algorithm may be required to resolve these integration issues, and usually, this kind of change is very expensive. How can we reduce this costs?.

Yes. I think everyone already knows the solution.To reduce this, we should clarify outcome of each sub-project.
Actually, changing software due to integration issues means "Requirement of that sub-project is changed"; Big Costs!. In this scenario, outcome of sub-project can be interface, data format and so on. In sub-teams' point of view, "Knowing exactly about outcome of other module" means "Knowing exactly what we can use and what we can supports". In my opinion, this is basic knowledge to reduce integration issues.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

"世有伯樂然後有千里馬, 天里馬常有而伯樂不常有." 라 했다.

좋은 사람을 알아 본다는 것은 그 만큼 힘든 일이고 어려운 일이다.

옛 중국에는 '사람을 추천했을 경우 추천받은 사람이 죄를 지으면 추천한 사람도 그와 같은 처벌을 받는다.'는 법이 있었다고 한다. 모르긴 몰라도, 그 반대로 추천받은 사람이 공을 세울 경우, 추천한 사람도 그 공을 나누어 가지지 않았을까?

따라서 사람을 추천한다는 것 혹은 추천받는 다는 것은 그 만큼 어렵고 또 중요한 일이란 뜻이다. 추천 받은 사람은 자신의 공과가 추천한 사람에게 그대로 이어짐을 명심해야하고, 추천한 사람또한 이러한 것을 충분히 고려한 후 추천해야 한다.

그렇지만 무엇보다도, 사람을 추천하기 전에 '좋은 사람을 알아본다'는 것이 얼마나 어려운 일인지 알고, '좋은 사람을 추천할 수 있는 사람' (伯樂)의 가치를 알며, 이를 소중히 여길 줄 아는 것! 이것이 아마도 가장 중요한 것이 아닐까? 그리고 나 또한 '좋은 사람을 알아볼 수 있는 안목'을 기르는데 노력해야 하지 않을까?

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Let's consider a software project.

Usually, we have two general way to make up team.
1st : We may organize one team for each project. That is, one team for one project. And this team - actually, team lead if we should pick only one person - is fully responsible for the project.
2nd : one team for each features.(for example, WAP team, MMS team etc...)

We cannot tell which model is better (each model has it's own pros and cons.).
But, in terms of time-critical project, 1st model is better.
In the 1st model, issues detected during project development are definitly under project team's responsibility. So, we don't need to struggle for finding appropriate team to handle those issues. And this project team tends to be active to resolve those. (But, Several teams may suffer same issues with high possibility, because sharing know-how and accumulating knowleges about each feature is difficult)

But, in 2nd model, it is difficult and takes time to know which team should handle those - for this, usually lots of communication overhead is required. So, each feature team tends to be passive. And they want to avoid being assiged to issues, because they don't have responsibility to succeed this project. (But, in this case, each feature team can accumulate know-how about features and expect synergy from this because team becomes expert for the feature!)

We should take attention to main difference between 1st model and 2nd model. That is just "Is there any ONE person who are fully responsible for the project?".

So, we would better to mix up this two models. (ex. 1st model for SW maintenance and enhancement; 2nd one for making product.)

My point to succeed in time-critical-project (ex. making product), (based on my experience..) is,

* There should be only ONE person who are fully responsible for a project and he/she should have enough authority to manage this project. Responsibility of several people means "No one under responsibility".

Does it seems too simple and trivial? But, it is not easy to obey this rule efficiently.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

Followings are all my personal opinion!

We always tell "good code". And lots of constraints are suggested for so-called "good code". For example, "number of line in one function should be less than xx", "number of class members should be less than xx", and so on.

Let's think from the basic. What is "good code". We don't need messy conditions for this. Just one factor!.
I want to define "good code" as "code that is easy-to-understand". Codes that is easy-to-understand, are easy to modify too.

Let's talk about this more.
"code that is easy-to-undertand" means, "It should be easy to know that the codes for and to predict the execution result.". Then what we should do to acheive this?

"Making code be small" can be an option. Anyway, small codes are easy. But, without reducing features and functionalities, decreasing code size enough is impossible. So, in practice, the is not a solution.

Let's convert the sentence into "Making stuffs required to be understood, be small". How about this? We can use lots of reliable module/component to do this. For example, let's think about standard library. We don't try to understand inside of each standard library functions because, we already trust the library enough. So, after understand inputs and outputs, we just use it. If we should understand inside of all those library functions, it will be nightmare. Too many things to understand!

In this context, we can say OOP(Object Oriented Programming), component-based software engineering, modularity, and so on. Making reliable and reusable modules/components can reduce stuffs required to be understood. Knowing input and output is much simpler than understanding inside codes of it.

This is my definition about "good code"

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

1. 스크린을 보지 않는다.
2. 단순화(화면, 내용)
- 좋은 Presentation은 더 추가할 것이 없는 presentation이 아니라, 더 뺄 것이 없는 presentation이다.
3. 1:1 시선.
4. 서론에서 줄거리
5. 결론에서 요약.
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

* Space vs. Speed
- Most famous one. (Memory space vs. execution speed) - details are omitted.

* Modularity vs. (Performance & Space)
- Well-designed-module should be stable. To be stable, there may be lots of 'parameter check', 'condition check', 'sanity check' and so on. Besides, for the safety reason, it may not trust passed memory space. So, it may allocates it's own memory space and try to copy data from passed memory to use it. Those make this trade-off. Well-designed-module hides it's information and stable as it is. But to be like this, it consumes speed and space.

* Abstraction vs. Debugging
- When software is stable, abstraction reduces maintenance costs very much. But, if not, debugging is more difficult than straightforward designed software, especially, to the engineer who are not accustomed to the software.

* low possibility to misuse vs. various and rich functionality
- It is clear...

* Backward-Compatibility vs. Innovation
- ...

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

In general, handling exception smoothly is very difficult. So, in many software, there are lots of prematured routine for exception handling. My recommend is, "just put "Assert" instead of premature exception handling(henceforth PEH)".

PEH give noisy information when exception is occurred, because software crashes at unexpected place due to PEH (Not the place where exception is actually raised).
Let's see following codes.

...
info = Get_personal_info(name);
if(!info){ return SYS_Fail;}
...
Personal_InfoT* Get_personal_info(char* name)
{
    ...
    int index = Search_with_name(name);
    if(index < 0) {return NULL;} // fail. (exception handling part)  ---- (*)
    ...
}

In this case, the place where exception is raised at first is (*). But, to handling exception, this function returns just 'NULL'. And at caller, it also returns 'SYS_Fail'. OK. It's reasonable. But, in practice, handling all these returned error smoothly requires lots of costs. So, in many cases, this is handled prematurely. And eventually, this error leads to software crash at unexpected place.

So, again, my point is just put 'Assert'. After all, we should try to debug all errors. 'Assert' is very helpful in debug. And then, we should decide whether remaining as 'Assert' or handling exception later - usually, exception from IO should be handled. This is more efficient in my opinion.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

Output files should be separated from input files. Usually, 'clean' option is supported to delete auto-generated-output-files. But, separating outputs at directory level is better - for example, 'out' directory is root directory for output.
This is very basic and fundamental. But, this also easily ignored.

Supporting 'clean' option is good. But, cleaning output files those are scattered over several different places, is difficult to maintain. And, in this case, to find some necessary output files is also difficult.
On the environment that output files are separated at directory level, programmer can tell easily that which is input and which is output. This means, he/she can know which are necessary files to build software without further efforts - easy to read software.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

조직의 최고 책임자가 조직 전체를 세세히 알 수 있는 작은 조직에서는 밥그릇 싸움이 일어나기 힘들다. 밥그릇 싸움은 조직의 크기가 어느 정도 이상 커졌을 때 주로 발생한다.

다음의 시나리오를 생각해 보자.

처음에 10명으로 시작한 회사가 있다. 이 회사의 일이 처음에는 10명이 열심히 하면 되었다. 그런데 차츰 회사가 성장하면서 10명으로는 도저히 감당할 수 없을 정도로 일의 양이 늘어났다. 그래서 회사는 사람을 더 뽑았고, 이런 과정이 몇번 발생하면서, 회사의 인원은 100명으로 늘어났다.

그런데 회사가 계속 일이 늘어나기만 할 수는 없다. 어느 날 부터, 100명 분의 일이 80명 분의 일로 줄어들었다. 그럼 20명은 놀아야 정상인데, 놀고 있다는 사실이 위쪽에 알려지면 놀고 있는 부서는 그 규모가 축소되어지게 되므로, 80명 분의 일을 100명분의 일로 늘리게 된다. 즉, 실무자들은 이 일이 80명 분의 일이라는 것을 알고 있으나, 관리자는 추가적이고, 비생산적인 20명분의 일을 만들어서 자기 부서의 규모를 유지하고자 하게 된다. 구체적인 예를 들어보자.

프로젝트 A, B가 있다. B는 50명 A는 10명의 인원이 배정되었으며, A는 B의 결과물을 받아서, 약간의 수정/개선 을 통해서 제품화되어 지게 된다. 프로젝트 납기일은 A는 B보다 2달 늦다. 이 상황에서 A는 B에서 어떤 base line이 되는 결과물이 나오기 전에는 Project에 관한한, Project가 진행되고 있음을 위쪽에 보여줄 어떠한 결과물도 만들어낼 수 없는 상황이다.

이때, 보통의 회사, 그리고 보통의 관리자라면, A 프로젝트의 10명의 인원에게, 무언가 생산적이고, 장기적인 일을 시키기 보다는(이런 일은 보통, Project진행상황을 진척시키는 것처럼 보이게하는데 별 도움이 되지 못한다.) 프로젝트가 진행되고 있다는 사실을 윗사람에게 보이기 위해, B의 결과물을 받기 이전에, A의 10명에게 B에서 하는 것과 똑같은 일을 시키게 된다. (A 프로젝트도 뭔가 진행되고 있다는 것을 보이기 위해...) 이 일은 명백히 B에서의 일과 중복된다. 그리고, B에서 어느정도 결과물이 나오게 되면, A는 자신이 했던 거의 모든 일은 다 버리고, B의 결과물을 받아와서 새로 A 프로젝트를 시작한다. 그리고 보통, 이 상태는 그 동안 A에서 "보여주기 위한 일"을 했던 그 상태보다 더 진보된 상태가 된다. (왜냐하면 50명의 산출물을 가져 왔으므로...). 이렇게 해서, A의 관리자는 프로젝트 A가 뭔가 진행되고 있는 것처럼 위에 보고 한다. 더 한심한 일은, 대부분의 윗쪽 상급관리자는 A 프로젝트의 관리자가 일을 잘 하고 있다고 생각하고, 여기에 무엇이 잘못되었는지 전혀 알지 못한다는 것이다.

이런 일은 특히 Software Project에서 많이 일어난다. 왜냐하면, Software 산업에서, 의사결정권을 가진 위쪽 사람들은 Software를 전혀 모를 사람이 대부분이기 때문이다. 이런 비효율은 계속해서 발생하고, 회사가 심각하게 어려워지기 전까지는 항상 사람이 부족한 것처럼 아래에서는 보고가 올라오고, 위헤서는 그렇게 보일것이다. 내가 너무 비약해서 글을 썼을 수도 있으나, 실제로 이런 과정을 몇차례 겪어보았으니... 쩝...

+ Recent posts