当前位置: 首页 > 面试题库 >

我必须发出数以千计的提醒,有什么办法避免每分钟发出响声吗?

康鹏云
2023-03-14
问题内容

我有一个像这样的结构:

type Notifications struct {
  Id int
  Start *time.Time
}

notifications := db.GetNotifications()

因此,现在我需要在时间与当前时间匹配时发出这些通知。

1  2018-11-07 09:05:00
2  2018-11-07 09:05:00
3  2018-11-07 09:15:00
..

对我来说,最简单的方法是使用代码:

ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()

for {
    <-ticker.C
    alerts := []Notification
    for _, n := range notifications {
      if n.Start == // same year, month, day, hour and minute {
        alerts = append(alerts, n) 
      }
    }

    sendNotifications(alerts)
    // TODO mutate the notifications to avoid duplicatation sending
}

有没有更有效的方法可以做到这一点?

匹配时间的最佳方法是什么,我必须在if语句中分别比较time.Now()的属性,例如年,月,日,小时和分钟吗?即,如果到达年,月,日,小时和分钟,则触发通知(忽略秒及以后的时间)


问题答案:

第一件事首先,比较时间值,使用Time.Equal,Time.Before和time.After方法。比较各个组件根本不可靠:

newYork, _ := time.LoadLocation("America/New_York")

t1 := time.Date(2018, 11, 8, 4, 0, 0, 0, time.UTC)
t2 := t1.In(newYork)

fmt.Printf("%v == %v?\n", t1, t2) // 2018-11-08 04:00:00 +0000 UTC == 2018-11-07 23:00:00 -0500 EST?

fmt.Println(t1.Day() == t2.Day()) // false
fmt.Println(t2.Equal(t1))         // true

https://play.golang.org/p/06RcvuI_1Ha

对于计划问题,我将使用time.Timer。

  1. 找出接下来要发出的通知
  2. 相应地设置或重置计时器
    1. 计时器触发后,转到1
    2. 如果添加了通知,请转到1
    3. 如果删除通知,则转到1

这是一个草图:

package main

import "time"

func main() {
    t := time.NewTimer(0)

    go func() {
        for range t.C {
            nextTwo := db.GetNextNotifications(2)

            // Sanity check
            if time.Until(nextTwo[0].Start) > 1*time.Second {
                // The timer went off early. Perhaps the notification has been
                // deleted?
                t.Reset(time.Until(nextTwo[0].Start))
                continue
            }

            go send(nextTwo[0])
            t.Reset(time.Until(nextTwo[1].Start))
        }
    }()

    resetTimer(t) // call as required whenever a notification is added or removed
}

func resetTimer(t *time.Timer) {
    next := db.GetNextNotification()
    t.Reset(time.Until(next.Start))
}


 类似资料:
  • 问题内容: 我正在使用我的帐户运行此简单示例,但该示例无法正常工作并给出以下错误: 这是我的代码 问题答案: 您可能正在尝试使用端口25上的Gmail服务器通过未经身份验证的连接将邮件传递给第三方。Gmail不允许您这样做,因为这样 任何人 都可以使用Gmail的服务器将邮件发送给其他任何人。这称为 开放中继 ,在早期是垃圾邮件的常见促成因素。Internet上不再接受开放中继。 您将需要让SMT

  • 我正在尝试获取每分钟出现数据的次数。日期看起来是这样的。第一个数字是一个整数,表示自Unix纪元以来的秒数,我将其转换为ISO 8601时间。第二个数字是双精度的。以“00”结尾的时间代表第0分钟,以“60”结尾的时间代表第1分钟。 代码: 我的输出是这样的: 但我正在寻找类似下面的东西(忽略新的分钟找到的文本) 我如何调整它,以便我跟踪当前分钟并添加到计数器,而不会过早地打印出计数器?

  • 问题内容: 在我看到的所有支持可选参数的编程语言中,都有一个模仿,即可选参数必须出现在声明的末尾。可选项目后不得包含必需的参数。是什么原因呢?我想这可能是编译器/解释器的要求。 问题答案: 好吧,如果它们在最前面,您将如何检测何时停止供应它们?唯一的方法是 在 可选参数 之后 变量类型是否不同。有点不可思议的要求,因此您只需将它们强制设置为最后是有意义的(省去了用于检测“最终”可选参数的复杂规则的

  • 问题内容: 我刚刚尝试了一个示例代码表单网络,它显示了如下警告 SimpleConvertImage.java:7:警告:com.sun.org.apache.xerces.internal.impl.dv.util.Base64是内部专有API,可以在以后的发行版com.sun.org.apache.xerces中删除。 internal.impl.dv.util.Base64; ^ Simpl

  • 问题内容: 我使用Java在Selenium WebDriver中编写了一些测试用例,并在网格(集线器和多个节点)上执行它们。我注意到有一些测试案例由于导致失败。避免并确保始终找到该元素的最佳且可靠的方法是什么? 问题答案: 您永远无法确定会找到该元素,实际上这是功能测试的目的- 告诉您页面上是否有任何更改。但有一两件事肯定是有帮助是添加等待这往往导致元素像

  • 我有一个典型的Antlr 4.5项目,其中有两个语法文件:MyLexer。g4和MyParser。Antlr从中生成6个输出文件:MyLexer。java,MyLexer。标记,MyParser。java,MyParser。令牌,MyParserBaseListener。java和MyParserListener。Java语言gradle任务都工作正常,因此输出文件都按预期生成、编译和测试。 问题