검색어 프로젝트/리스크관리에 대한 글을 관련성을 기준으로 정렬하여 표시합니다. 날짜순 정렬 모든 글 표시
검색어 프로젝트/리스크관리에 대한 글을 관련성을 기준으로 정렬하여 표시합니다. 날짜순 정렬 모든 글 표시

2009년 3월 2일 월요일

좋은 PM은 훌륭한 리스크 관리자

프로젝트에서 가장 중요한 활동 중에 하나가 리스크 관리입니다. 프로젝트 실패의 원인의 대부분이 리스크 관리를 하지 않거나 하더라도 부실하게 하는 데 있습니다. 성공하는 프로젝트관리자는 우수한 리스크 관리자입니다.

성공하는 프로젝트는 대부분 성공 가능한 범위 및 일정을 가지고 리스크를 잘 관리한 프로젝트입니다. 반면, 성공 가능한 범위 및 일정을 가지고 시작한 프로젝트라도 리스크 관리에 거의 신경을 쓰지 않으면 예상치 못한 돌발 변수에 프로젝트는 실패하기 쉽습니다.
프로젝트 리스크 관리를 하다 보면 소프트웨어 프로젝트는 정말 가시밭길을 걷고 있다는 생각이 듭니다. 웬만한 크기의 프로젝트에서 리스크 수십 개를 찾아내기란 그리 어렵지 않기 때문입니다. 하지만 미리 발견되고 관리되는 리스크들은 그 위험을 현저히 낮출 수 있고, 다른 대처 방법들을 얼마든지 찾을 수 있습니다.

 프로젝트에서 리스크 관리는 다음과 같은 절차로 진행됩니다.

1. 리스크관리 책임자 임명 - 대부분의 중소규모의 프로젝트는 프로젝트관리자가 리스크관리자도 겸하지만 프로젝트가 대단히 크거나 특수한 경우 리스크관리자를 별도로 임명합니다.

2. 리스크 인지 - 리스크는 프로젝트에 관련된 모든 사람이 찾아내야 합니다. 추후 인지하지 못한 리스크 때문에 프로젝트가 지현되거나 실패하면, 리스크 인지가 소흘했기 때문입니다. 리스크 인지는 프로젝트 초기에 한번만 하는 것이 아니고, 프로젝트가 끝날 때까지 꾸준히 찾아야 합니다. 리스크관리자는 사소하게 흘려버리는 걱정거리들을 정리하고 계수화해서 리스크 관리 항목으로 끌어들여야 합니다.

3. 리스크 분석 - 인지된 리스크는 분석하여 분류를 해야 합니다. 그리고 발생가능성(P)과 파급효과(I)로 나누어서 분석하여 수치화를 해야 합니다. 각각은 1~5까지의 수치로 정량화를 할 수 있는데, 이때 주관적인 판단이 필요합니다. 발생가능성이 몇%가 될지를 정확하게 예측한다는 것이 거의 불가능하기 때문입니다. 그에 비하여 파급효과는 예측이 좀더 쉽습니다. 그 일이 일어났을 때 발생할 수 있는 피해를 일정이나 금액으로 환산해서 예측할 수 있습니다.

4. 리스크 우선순위화 - 프로젝트에서 관리하는 리스크는 대단히 많은 수가 됩니다. 이를 모두 동일하게 관리하기란 쉽지 않고 비효율적입니다. 따라서 우선순위가 높은 리스크를 집중적으로 관리하는 것이 좋습니다.

아래 노출도 계산 공식을 엑셀의 수식으로 변화하면 입력하면 자동으로 해당 리스크의 노출도가 계산이 됩니다.
노출도(E, Exposure) = (P/5-0.1)*0.05*(2^(I-1))
P = 발생가능성(Probability)
I = 파급효과(Impact)


낮은 노출도: 0.05 미만
중간 노출도: 0.05 이상 0.15 미만
높은 노출도: 0.15 이상

5. 리스크 대처 계획 - 리스크가 문제가 되지 않도록 미리 대처를 하거나 리스크가 발생해도 되도록 대비를 하는 것입니다. 예를 들어 개발자가 퇴사할 징후가 보일 때 다음과 같은 대응책을 마련할 수 있다.
  • 개발자가 퇴사하지 않도록 노력한다.
  • 개발자가 퇴사하더라도 보충할 개발자를 미리 사내에서 물색해 놓는다.
  • 사내에서 보충한 개발자를 찾지 못하면, 외부 채용 활동의 준비 단계를 해 놓는다. 즉, 채용 공지를 하고, 이력서를 분석하여 채용자 후보를 미리 물색해 놓는다.
  • 해당 개발자의 모듈을 다른 개발자와 많은 부분 공유하도록 계획 한다.
  • 아예 해당 개발자를 프로젝트에서 제외하고 진행한다.

6. 리스크 감시 - 프로젝트가 진행되면서 리스크는 계속 변합니다. 따라서 리스크를 지속적으로 감시해야 합니다. 리스크의 모든 기록은 리스크관리대장을 만들어서 기록해야 합니다. 리스크관리대장에는 다음과 같은 것들이 적힙니다.
  • 리스크 제목
  • 리스크 내용
  • 리스크 분류
  • 리스크 발생 가능성
  • 리스크 파급 효과
  • 리스크 관리계획
  • 리스크 발생 시 대처 계획
  • 리스크 대처 기록
  • 리스크 재평가 기록
리스크를 주기적으로 재평가하고 우선순위를 재정렬하고, 리스크 대처 계획을 갱신해야 합니다. 이와 더불어 새로운 리스크를 인지하기 위해서 지속적인 리스크 감시를 해야 합니다. 리스크관리대장에 내용이 꾸준히 쌓이면, 프로젝트가 끝난 후에도 다른 프로젝트에서 참조할 수 있습니다. 이 때 놓치기 쉬운 리스크를 쉽게 찾아낼 수도 있고, 리스크에 어떻게 대처해서 문제를 해결했는지도 도움을 얻을 수 있습니다.



2009년 1월 19일 월요일

프로젝트는 연습이 아니다.

필자는 수많은 소프트웨어를 개발해왔고, 주위에서 여러 프로젝트를 봐왔습니다.
그러면서 성공한 프로젝트와 실패한 프로젝트도 많이 봐 오면서 그 차이에 대해서도 많이 생각해 왔습니다.

물론, 성공한 프로젝트는 모두들 알고 있는 요소들이 있습니다. 
상세하고 꼼꼼한 일정관리, 꾸준한 리스크관리, 인력관리, 품질관리 등등 이미 알려진 것들입니다. 비단 S/W 프로젝트가 아니더라도, 빌딩을 만들 때도 당연히 필요한 프로젝트 관리의 요소들입니다.

그런데, 유독 소프트웨어 개발 프로젝트에서 종종 벌어지는 현상이 있습니다. 이것이 프로젝트에 큰 리스크가 되고 프로젝트를 실패하게 만드는 원인이 되기도 합니다.

이것은 바로 "프로젝트를 연습처럼 생각한다"는 겁니다. 연구, 공부처럼 생각합니다.

"요즘 Python이 인기인데, A모듈에서는 Python을 써야겠다."
"이번 프로젝트는 UML로 설계를 하겠다."
"Flex로 UI를 만들면 쉽다고 하는데, Flex를 쓰자"
"A라는 DB가 빠르고 가볍다고 하는데, 그걸 써보자"
"요즘 B기술이 대세인데, 어차피 공부해야 할 거 프로젝트 하면서 배우자"

실제로 개발자들은 실제 프로젝트에서 많이 배우는 것이 사실이지만, 거의 경험이 없는 기술을 단지 "배우기 위한 목적"이나 "좋아 보여서" 사용한다면 이는 프로젝트에 큰 리스크가 될 수 있습니다.

필자는 개발자들에게 늘 강조하는 것이 "프로젝트는 연습이 아니다.", "프로젝트는 검증된 기술을 가지고 하는 것이다."입니다. 물론 검증된 기술과 아닌 것의 경계는 모호하지만 이는 경험으로 판단해야죠. 충분히 성공할 수 있는 기술의 조합으로 프로젝트를 해야죠. 그렇다고 하더라도, 프로젝트 중간에는 수많은 변수들이 있어서 성공이 보장된 것이 아닙니다. 아직 검증이 안되었지만, 프로젝트에 꼭 필요한 기술이라면, 미리 또는 요구분석 시에 Prototype을 만들어보면서 검증을 하는 것이 좋습니다. 모든 기술을 다 검증할 필요는 없지만, 검증이 필요한 기술을 프로젝트에 직접 사용할 경우 실패할 수도 있습니다.

또 개발자들이 충분히 연습이 되어 있지 않아서 능숙하게 사용하지 못한다면, 일정을 지연시키는 큰 원인이 됩니다. 이런 경우는 이미 익숙한 옛날 기술을 사용하는 것이 나은 경우가 많습니다. 

Research Project라면 얘기가 다르죠. Research Project의 목적은 연구이기 때문에 검증 안된 기술을 얼마든지 사용해도 되죠. 이 경우 요구사항의 상세도도 일반 프로젝트와 다르고 일정의 중압감도 다르기 때문에 기술에 집중할 수 있습니다. 평상 시에 크고 작은 Research Project를 자주 수행해야 실제 프로젝트에 적용할 수 있는 기술을 풍부하게 보유할 수 있습니다.

프로젝트를 연습이라고 생각한다면, 프로젝트 실패로 가는 지름길로 가고 있는 것입니다. 자신이 지금 어떤 프로젝트를 하고 있는지 잘 구분해야 합니다.

2025년 12월 11일 목요일

리스크 기반 버퍼: 불확실성을 숫자로 관리하기



"이 프로젝트 언제 끝날까요?"

"음... 버퍼 20% 넣어서 6주요."

잠깐, 왜 20%인가요?

"그냥... 경험상?"

이제 추측이 아닌 계산으로 버퍼를 정합시다.

버퍼의 딜레마

프로젝트 버퍼, 어떻게 정하시나요?

대부분 이렇게 합니다:

  • "무조건 30% 추가"
  • "지난번에 늦었으니 50%"
  • "중요한 프로젝트니까 100%"
  • "그냥 느낌상..."

결과는? 너무 적으면 프로젝트 지연, 너무 많으면 자원 낭비와 파킨슨 법칙.
적정선은? 아무도 모릅니다.

리스크 점수 시스템

리스크를 측정하면 버퍼를 계산할 수 있습니다.

class RiskBasedBuffer {
  calculateBuffer(baseEstimate, risks) {
    // 리스크 요소별 가중치
    const factors = {
      신기술_사용: { weight: 3, score: risks.newTech },
      팀_경험_부족: { weight: 3, score: risks.teamExp },
      요구사항_불명확: { weight: 3, score: risks.unclear },
      복잡도: { weight: 2, score: risks.complexity },
      의존성: { weight: 2, score: risks.dependency },
      변경_가능성: { weight: 2, score: risks.changeProb }
    };
    
    // 리스크 점수 계산 (0-100)
    let totalRisk = 0;
    let maxRisk = 0;
    
    for (const factor in factors) {
      const f = factors[factor];
      totalRisk += f.weight * f.score;
      maxRisk += f.weight * 10;
    }
    
    // 리스크 비율로 버퍼 계산
    const riskRatio = totalRisk / maxRisk;
    const bufferPercentage = 10 + (riskRatio * 60); // 10-70%
    
    return {
      baseEstimate,
      bufferPercentage: Math.round(bufferPercentage),
      bufferDays: Math.round(baseEstimate * bufferPercentage / 100),
      totalEstimate: baseEstimate + Math.round(baseEstimate * bufferPercentage / 100)
    };
  }
}

실제 적용 예시

두 프로젝트를 비교해보겠습니다.

고위험 프로젝트: 블록체인 결제 시스템

const highRiskProject = {
  base_estimate: 60, // 일
  
  risks: {
    newTech: 8,      // 블록체인 첫 도입
    teamExp: 9,      // 팀 경험 없음
    unclear: 7,      // 스펙 미완성
    complexity: 7,   // 분산 시스템
    dependency: 6,   // 외부 API 다수
    changeProb: 8    // 자주 바뀜
  }
  
  // 계산 결과:
  // 리스크 점수: 67/100
  // 권장 버퍼: 50% (30일)
  // 최종 예상: 90일
};

저위험 프로젝트: 관리자 페이지 CRUD

const lowRiskProject = {
  base_estimate: 30, // 일
  
  risks: {
    newTech: 1,      // 익숙한 스택
    teamExp: 1,      // 경험 풍부
    unclear: 2,      // 명확한 스펙
    complexity: 2,   // 단순 CRUD
    dependency: 1,   // 독립적
    changeProb: 2    // 거의 없음
  }
  
  // 계산 결과:
  // 리스크 점수: 15/100
  // 권장 버퍼: 15% (5일)
  // 최종 예상: 35일
};

똑같이 "경험상 20%"를 넣었다면?
블록체인 프로젝트는 실패하고, CRUD는 자원을 낭비했을 겁니다.

동적 버퍼 관리

버퍼는 한 번 정하고 끝이 아닙니다.
매일 소비를 추적하고 패턴을 분석해야 합니다.

class DynamicBufferManager {
  constructor(totalBuffer) {
    this.totalBuffer = totalBuffer;
    this.consumed = 0;
    this.projectProgress = 0;
  }
  
  updateStatus(progress, bufferUsedToday) {
    this.projectProgress = progress;
    this.consumed += bufferUsedToday;
    
    const consumptionRate = this.consumed / this.totalBuffer;
    const idealRate = this.projectProgress;
    
    // 버퍼 소비가 진행률보다 빠르면 위험
    if (consumptionRate > idealRate * 1.5) {
      return {
        status: "🔴 위험",
        action: ["근본 원인 분석", "스코프 재검토", "자원 추가"]
      };
    } else if (consumptionRate > idealRate * 1.2) {
      return {
        status: "🟡 주의",
        action: ["리스크 재평가", "일정 조정 검토"]
      };
    }
    
    return {
      status: "🟢 정상",
      remainingBuffer: this.totalBuffer - this.consumed
    };
  }
}

몬테카를로 시뮬레이션

더 정교한 예측을 원한다면 시뮬레이션을 돌려보세요.

import random

def monte_carlo_buffer(tasks, iterations=1000):
    """1000번 시뮬레이션으로 적정 버퍼 계산"""
    
    results = []
    
    for _ in range(iterations):
        total_time = 0
        
        for task in tasks:
            # 각 작업은 최선/최악 케이스 사이에서 랜덤
            best_case = task["estimate"] * 0.7
            worst_case = task["estimate"] * 2.0
            
            # PERT 분포로 시뮬레이션
            simulated = random.triangular(
                best_case, 
                worst_case, 
                task["estimate"]
            )
            total_time += simulated
        
        results.append(total_time)
    
    # 결과 분석
    results.sort()
    p50 = results[500]  # 50% 확률
    p90 = results[900]  # 90% 확률
    
    recommended_buffer = p90 - p50
    
    return {
        "base": p50,
        "buffer_90": recommended_buffer,
        "confidence_90": p90
    }

# 사용 예시
tasks = [
    {"name": "설계", "estimate": 5},
    {"name": "개발", "estimate": 15},
    {"name": "테스트", "estimate": 8}
]

result = monte_carlo_buffer(tasks)
print(f"50% 확률: {result['base']:.0f}일")
print(f"90% 확률: {result['confidence_90']:.0f}일")
print(f"권장 버퍼: {result['buffer_90']:.0f}일")

버퍼 소비 패턴 분석

버퍼가 왜 소비되는지 추적하면 다음 프로젝트를 개선할 수 있습니다.

class BufferConsumptionTracker {
  recordConsumption(day, consumed, reason) {
    this.history.push({ day, consumed, reason });
    
    // 패턴 분석
    const triggers = this.identifyTriggers();
    
    if (triggers[0].reason === "요구사항 변경") {
      console.log("⚠️ 요구사항 동결 필요");
    } else if (triggers[0].reason === "기술적 이슈") {
      console.log("⚠️ 기술 검증 강화 필요");
    }
  }
  
  identifyTriggers() {
    // 원인별 버퍼 소비 집계
    const reasons = {};
    this.history.forEach(h => {
      reasons[h.reason] = (reasons[h.reason] || 0) + h.consumed;
    });
    
    // 상위 3개 원인 반환
    return Object.entries(reasons)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 3)
      .map(([reason, days]) => ({ reason, days }));
  }
}

실전 사례: 결제 시스템 리뉴얼

한 핀테크 회사의 실제 사례입니다.

초기 계획 (경험적 버퍼)

  • 예상: 3개월 + 20% = 3.6개월
  • 실제: 5.5개월 (실패!)

리스크 분석 후 재계획

리스크 평가:
- PCI 규정 준수: 9점
- 레거시 연동: 8점  
- 실시간 처리: 7점
- 보안 경험 부족: 8점

리스크 점수: 72/100
권장 버퍼: 55%
새 예상: 4.65개월

결과

  • 실제: 4.5개월 (성공!)
  • 버퍼 사용: 85%

리스크 기반 버퍼가 프로젝트를 구했습니다.

체크리스트

리스크 기반 버퍼 도입 시:

  •  리스크 요소 정의 (기술, 팀, 요구사항)
  •  각 요소 0-10점 평가
  •  가중치 적용하여 점수 계산
  •  버퍼 비율 산출 (10-70%)
  •  일일 버퍼 소비 추적
  •  주간 리스크 재평가
  •  트리거 포인트 설정
  •  버퍼 소비 원인 분석
  •  패턴 기반 개선

마무리

리스크 기반 버퍼는 "감"이 아닌 "계산"입니다.

불확실성은 제거할 수 없지만, 측정하고 대비할 수는 있습니다.

다음 프로젝트에서 리스크 기반 버퍼를 시도해보세요.
추측이 아닌 데이터로 프로젝트를 관리하는 첫걸음이 될 겁니다.


체계적인 프로젝트 관리가 필요하신가요? Plexo를 확인해보세요.