Current : SDE-2 with ~4 years of experience.
Design an alarm clock
Alarm clock should have the following functions
AddAlarm(time)
DeleteAlarm(time)
UpdateAlarm(oldtime, newtime)
Snooze(time, delaytime)
Write a program, on matching alarm times
system should Print "Wake Up".
Solution :
package main
import (
"fmt"
"time"
)
type AlarmClock struct {
alarms map[string]time.Time
}
// NewAlarmClock creates a new AlarmClock instance.
func NewAlarmClock() *AlarmClock {
return &AlarmClock{
alarms: make(map[string]time.Time),
}
}
// AddAlarm adds a new alarm to the clock.
func (ac *AlarmClock) AddAlarm(label string, alarmTime time.Time) {
ac.alarms[label] = alarmTime
fmt.Printf("Added alarm '%s' at %s\n", label, alarmTime.Format("15:04:05"))
}
// DeleteAlarm deletes an alarm from the clock.
func (ac *AlarmClock) DeleteAlarm(label string) {
if _, exists := ac.alarms[label]; exists {
delete(ac.alarms, label)
fmt.Printf("Deleted alarm '%s'\n", label)
} else {
fmt.Printf("Alarm '%s' does not exist\n", label)
}
}
// UpdateAlarm updates an existing alarm to a new time.
func (ac *AlarmClock) UpdateAlarm(label string, newTime time.Time) {
if _, exists := ac.alarms[label]; exists {
ac.alarms[label] = newTime
fmt.Printf("Updated alarm '%s' to %s\n", label, newTime.Format("15:04:05"))
} else {
fmt.Printf("Alarm '%s' does not exist\n", label)
}
}
// Snooze snoozes an alarm by adding a delay.
func (ac *AlarmClock) Snooze(label string, delay time.Duration) {
if alarmTime, exists := ac.alarms[label]; exists {
newTime := alarmTime.Add(delay)
ac.alarms[label] = newTime
fmt.Printf("Snoozed alarm '%s' to %s\n", label, newTime.Format("15:04:05"))
} else {
fmt.Printf("Alarm '%s' does not exist\n", label)
}
}
// Start checks for matching alarm times and prints "Wake Up".
func (ac *AlarmClock) Start() {
for {
for label, alarmTime := range ac.alarms {
if time.Now().After(alarmTime) {
fmt.Printf("Wake Up! Alarm '%s' triggered at %s\n", label, alarmTime.Format("15:04:05"))
delete(ac.alarms, label) // Remove the alarm after it triggers
}
}
time.Sleep(1 * time.Second)
}
}
func main() {
ac := NewAlarmClock()
// Add some alarms
ac.AddAlarm("Morning Alarm", time.Now().Add(5*time.Second))
ac.AddAlarm("Meeting Reminder", time.Now().Add(10*time.Second))
// Update an alarm
ac.UpdateAlarm("Morning Alarm", time.Now().Add(8*time.Second))
// Snooze an alarm
ac.Snooze("Meeting Reminder", 5*time.Second)
// Start the alarm clock
go ac.Start()
// Keep the main function alive
select {}
}
Follow ups:
1. Interview asked, you are running infine loop, can we improve this.
- I told we use a min heap, pull the next min alarm time, and sleep till next alarm.
- in case of update existing alarm or snooze, we have to reset the sleep time, if updated alarm becomes the new min time.
2. Feedback by interviewer : expectation was to use OS scheduler for next Trigger, instead of time.sleep(). interview told this is how the cron jobs work.
Guys help me understand : how the cron jobs work?, time.sleep is not used in crons?
Similar post i got : https://leetcode.com/discuss/interview-question/876976/amazon-sde-intern-phone-final-round


