프로그래밍Go 개발자

Go에서 time.Timer 및 time.Ticker를 사용할 때 알아야 할 사항은 무엇인가요? 중요한 차이점, 올바른 사용법의 특징 및 중지/리셋 시의 일반적인 오류는 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

time 패키지는 두 가지 유용한 도구인 TimerTicker를 제공합니다.

  • Timer는 단일 지연을 위해 사용됩니다(지정된 시간 후 한 번 발생).
  • Ticker는 정기적인 주기적 이벤트를 위해 사용됩니다(인터벌).

주요 차이점:

  • Timer는 발생 후 "소멸"되고, 다시 사용하려면 재설정(Reset)해야 합니다.
  • Ticker는 명시적으로 Stop() 메서드로 중지될 때까지 이벤트를 생성합니다.

사용 시 특징:

  • 작업 완료 시 리소스 누수를 방지하기 위해 항상 Timer/Ticker에서 Stop()을 호출해야 합니다.
  • Timer에서 Stop()을 호출한 후, "비우기" 처리가 필요할 수 있습니다: 만약 타이머가 Stop() 전에 발생했으면, 채널에서 읽어야 합니다.

Timer의 올바른 사용 예:

t := time.NewTimer(2 * time.Second) defer t.Stop() // 필수! select { case <-t.C: fmt.Println("시간이 다 됐습니다!") case <-otherDone: if !t.Stop() { <-t.C // 필요시 채널을 비움 } }

함정 질문

t.C에서 값을 받은 후 타이머를 즉시 재사용할 수 있나요? t.Stop()을 호출하지 않으면 어떻게 될까요?

답변: 타이머는 Stop() 호출과 채널에서 읽기를 하지 않고 즉시 재설정되어서는 안 됩니다. t.Stop()을 호출하지 않으면 "죽은" 고루틴이 남거나 다음 루프에서 예기치 않은 트리거가 발생할 수 있습니다(채널이 비워지지 않음). 올바른 사용법: Stop()을 호출하고, 만약 Stop()이 false를 반환하면 반드시 t.C에서 읽어 채널을 비워야 합니다.

주제와 관련된 일반적인 오류 사례


이야기

스타트업의 알림 서비스에서 배달 시도 재설정을 위해 타이머를 사용했습니다. 발생 후 즉시 중지하지 않고 재설정했습니다 — 결과: 고루틴이 증가하고, 프로세스가 "누수"되어 시스템이 메모리 부족으로 다운되었습니다.

이야기

대규모 e-commerce 프로젝트에서 주기적인 상품 업데이트를 위해 사용된 Ticker가 핸들러 완료 시 중지되지 않았습니다. 핸들러는 사용자가 삭제된 후에도 "매달려" CPU를 계속 소모하였습니다.

이야기

테스트에서 타이머의 Stop()을 호출하지 않았습니다 — 테스트가 랜덤으로 멈추었습니다, 타이머의 채널이 비워지지 않아 두 번째 "핑"을 대기했지만 결코 오지 않았습니다.